65

My boss decided recently to try out an outsourcing group "for increased capacity" as we modify an existing application to add new features. Despite my concern that the group he chose didn't seem to communicate well and wasn't asking enough questions to truly understand and be effective, we went with them anyway.

We set them up to collaborate on our Git repository (hosted on GitHub). We created a branch just for them (TheOutsourcedBranch, we'll call it) and requested that they to do all of their work within this branch.

Additionally, we asked that they push their commits at the end of each day so that we can get a decent idea of how fast they work and (more importantly) how good their code is.

Today they pushed for the first time. Five commits, all of them in master. I'm trying to figure out how to move their commits from master into TheOutsourcedBranch, without losing the work they've done (although from the looks of it, we're going to have to throw it away anyway).

Visual Reference -- Orange dots are their commits, gray are mine.

Orange dots are their commits, gray dots are mine.

I know there are a zillion questions about rebasing (and that might be what I need to do here) but I'm having a hard time figuring out which of them apply to my specific case. And in case it matters, the outsourcing group and myself are the only people that are really using the repo right now.

Thanks in advance!


Edit: I may have found what I'm looking for: Move the most recent commit(s) to a new branch with Git

I'd like to check my understanding, though. Locally, I create a branch off of master (TheOutsourcedBranch), which would contain everything A-H. Then I reset master back to C. Master would now contain A-C.

Assuming that is correct, that would be fine for me (locally). But then what do I need to do to "force" the remote repository (GitHub) to accept my local view of how things played out and discard its version of the history?

Once this has played out I think I can re-work this question to make it more generic/informative and cut out some fluff--otherwise it's probably a good candidate for deletion, I would guess.

Community
  • 1
  • 1
Anthony Compton
  • 5,271
  • 3
  • 29
  • 38

2 Answers2

71

Getting the branch is easy:

git branch their-branch master
git reset --hard master $SHA1_OF_C
git push --force $SHARED_REPO_REMOTE

This will rewrite history; it creates a new branch that is equivalent to the current master branch named their-branch, then resets your local master to point to a random SHA1 (...or branch, or tag, or whatever), and finally forcibly updates the remote repository branch to match your local branch.

That delivers exactly the situation you want.

Caveats: this will rewrite history, and can screw up anyone who has built off the old master. Watch out for merge problems following.

No rebasing desired or required.

(As an aside, I suggest you either give them a staging repository, or get them to use git send-email, or use GitHub pull requests, or otherwise prevent them pushing to master until they get it right. Which, based on your summary, might be some time away.)

Daniel Pittman
  • 16,733
  • 4
  • 41
  • 34
  • 17
    Just wanted to share that this solved the same problem for me - but I had to change the second step to `git reset --hard $SHA1_OF_C` (removing the reference to master); prior to this I was getting `fatal: Cannot do hard reset with paths.` . Possibly this is a change in a recent version of git? – Chris O'Kelly Jun 25 '15 at 01:07
  • 1
    After I do git reset --hard my local repository become behind and git push fails because of that. – vanowm May 15 '16 at 02:02
  • 1
    Don't ever use `push --force`, it's a bad idea. It will seriously corrupt history on any other users who have already pulled. Even worse, if you have your Git log integrated into other systems such as Redmine, Jira, etc then it can seriously corrupt the databases and be quite difficult to clean up. – Adam Sep 08 '16 at 07:14
  • Clarification for what @Adam said is provided on http://stackoverflow.com/questions/40054992/git-move-pushed-commits-to-a-new-branch-rename-branch-instead-of-force-pushin – Jorjon Feb 26 '17 at 07:53
  • 1
    What is $SHARED_REPO_REMOTE in this context? – Tyrel Kostyk Jun 26 '20 at 17:36
-1

Have them make a branch off of each bit of work from the same starting point for each ticket they work on. Have them merge the work to a RC branch. You can merge your work to the RC branch. This will allow you to test often. See the workflow we have here:

https://plus.google.com/109096274754593704906/posts/R4qkeyRadLR

Let me know if you have any questions about it. It works well for us.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • That's pretty much the exact workflow we're using already. But the problem here is that they've make commits and pushed them--but I need them to be on a different branch, instead of in master. – Anthony Compton Jan 31 '12 at 21:14
  • Without forcing a push, you can get them to use a different branch name. Branches are just pointers to commits. – Adam Dymitruk Jan 31 '12 at 21:38