Skip to content

Instantly share code, notes, and snippets.

@panaggio
Created January 26, 2014 03:09
Show Gist options
  • Save panaggio/8627807 to your computer and use it in GitHub Desktop.
Save panaggio/8627807 to your computer and use it in GitHub Desktop.

To start: there are three locations:

  • your local machine (you're editing files here)
  • your personal remote (this lived on github)
  • the mozilla remote (this also lives on github)

When working on "things", the basic idea is to, before you start editing things, make sure all three locations have the same develop branch. The mozilla remote is the boss here, so the idea is to ask it what the most up to date code is, then update your local machine develop branch to be the same as that, and to then push your local copy up to your personal remote:

$> git fetch mozilla

remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 1 (delta 0)
Unpacking objects: 100% (1/1), done.
From https://github.com/mozilla/appmaker
   b3ed06d..ca09e64  develop    -> mozilla/develop

$> git checkout -B develop mozilla/develop

The first command asks the mozilla remote for its most up to date information, and the second command says "create a local branch called develop on my machine, with as content whatever is in mozilla/develop. IF I already have a branch called develop, overwrite it".

(An alternative way to do this if you already have a develop branch is to issue git fetch mozilla, and then git checkout develop followed by git pull, which checks out your local copy of the develop branch, and then tries to merge in the changes on mozilla's version of the develop branch. Usually this will work, sometimes it won't. I hate that 1% of the time so much I just always use git checkout -B develop mozilla/develop because I just don't want to even bother with problems on the develop branch =)

To then work on something, create a new branch based on your local develop: $> git checkout -b totallyAppropriateBranchName, and work on the code in that. Once you're happy with what you have, add your files, commit them, and push them to your personal github.com remote using your "For this work only" branch name.

Now, let's be honest: things will go wrong. Git works fine when things work fine, but sometimes things are far from fine and we need to make git do what we want. Or rather, we need to use git to achieve what we want. So...

  1. you've been working in the develop branch by mistake!

No worries. Let's make a new branch based on what you have right now:

$> git checkout -b BetterLateThanNever

now we have a branch BetterLateThanNever with your code changes on top of develop. First, this might already be good enough! git add, commit, and push to your personal remote, and then on github.com you can do a pull request. If nothing catastrophic happened, this should just work.

  1. Yeah it totally didn't work, it says it cannot be merged!

Already, rebase time. You have your remove code safely sitting on github, and you have a local branch that needs to be brought in line with mozilla's codebase.

step 1: git fetch mozilla + git checkout -B develop mozilla/develop step 2: git chechkout BetterLateThanNever step 3: git rebase -i develop

this third step says "try to come up with the path from the most up to date develop branch to the code I have in my BetterLateThanNever branch. The -i says "let's do this interactively", which is very, very useful.

Git will first pop up a text editor (probably vi) with all the commits that it sees in your branch. Usually, you want to keep the first commit on "pick", but you want to change the remainder to "squash", or just "s" for short (git accepts both). If you've changed this you can save and quit, and then git will start trying to put this commits on top of the code in the develop branch. This may fail, and then it'll signal a merge conflict!

Again, no worries. You're now in "rebase mode", so we can first find out where the problems are with git status. Anything marked as "both modified" is a file that has code that got changed in mozilla/develop, as well as by you in your local copy. Open up each file, look for the merge conflict markers, and fix the code as best as you think should be fixed. code between "HEAD" and "===" is what git sees in the mozilla branch, and everything after "===" and the merge marker was your code. Fix the code so that it's all correct again, and when you're done changing all the files that need fixing:

$> git add .
$> git commit -m "rebasing..."
$> git rebase --continue

If you're lucky, there was only one problematic commit, and git will finish without any more complaints. If it does, however, simply repeat the process: git status to see which files have merge conflicts, fix them, and do another add/commit. repeat as necessary.

Finally, git will finish and pop up an editor (probably vi again) with the commit messages. Simply delete all but the first, save and quit, and git will finalise the rebase.

If you have several manual-fixes, you can actually run git rebase -i develop again now, simply to squash all the rebasing commits you added. Again keep the first commit as "pick" and set the rest to "squash". Git should now simply run through it wihtout any merge conflicts, because you already solved those. once it's done, you'll have a single commit with all your changes in it.

We need to push that up to your github remote, but you'll need to "Force" it because github will see one commit tree on github.com, and a completely different tree coming in from your push instruction. You want yours to win, so:

$> git push origin BetterLateThanNever -f

Done! We've rebased and this code can be merged in from a pull request now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment