add 9-conflicts
[gitjutsu.git] / 7-tothefuture
blob263edae559f44fb62ddf0194f06408d20ca6b7e2
2 Branches are great for trying new things, but you'll probably want some tools for moving your changes between them.
4 Simple scenario:
5 * You're on the master branch.
6 * You create a new branch called crazyidea.
7 * You do some work on it.
8 * You find that it is a great success, and you want the work to go back into master.
10 Well, first off, you'll want to checkout master because that is the branch you want to change, not crazyidea:
12 And second, you'll want to, uh, somehow.. add those changes to master.
14 There are two very different ways to do this: they are called "merge" and "rebase".
16 It is very important to understand the difference between merge and rebase and use the appropriate tool.
18 Fortunately, this is a very special case called a "fast-forward", and they behave exactly the same.
19 Because crazyidea is in the future (or, more precisely, master is an ancestor of crazyidea), all Git has to do is move master forward to where crazyidea is.
21 In this case you can do either
22 [code]
23 git merge crazyidea
24 [/code]
26 [code]
27 git rebase crazyidea
28 [/code]
30 Both will fast-forward master to crazyidea.
32 Now then, here's a less simple scenario:
33 * You're on the master branch.
34 * You create a new branch called crazyidea.
35 * You do some work on crazyidea.
36 * You go back to master.
37 * You do some different work on master.
38 * You go back to crazyidea.
39 * You want to see the work you've done on master in crazyidea.
41 This is a hard problem to solve.
43 Git cannot simply move crazyidea to master, as you would lose the work you've done on crazyidea.
45 Remember, if you screw this up, you can always find your old commits using "git reflog" (or at least, you can do that until 30 days after they disappear).
47 [TODO: Remove redundant information about patches?]
49 So, first off, here is how rebase would approach the problem:
50 * Create a list of the commits that are in crazyidea but not in master.
51 * Translate each commit into a "patch", a representation of what changed between the commit and the previous version.
52 * Move crazyidea to master.
53 * Attempt to replay what you did by applying the patches in sequence.
55 You can do this by checking out the crazyidea branch and doing
56 [code]
57 $ git rebase master
58 [/code]
60 Git will "attempt" to replay what you did, but there's no guarantee that it will actually work, as sometimes patches don't apply.
62 It probably won't work if you modified the same lines of the same file in each branch.
64 If it can't apply a patch, Git will stop the process and ask you to resolve the conflict.
66 Remember, when you do a rebase that isn't a fast-forward, you're creating an alternate version of history.
67 In this alternate history, you built your current branch (crazyidea) on top of everything that's in the other branch (master).
70 Git merge does this instead (actually, it can use many different strategies, but this is the common one):
71 * Find the "merge base" of crazyidea and master, that is, the point where they started to diverge.
72 * Generate a patch that would update the merge base to master.
73 * Generate a patch that would update the merge base to crazyidea.
74 * Apply both patches to the merge base at once.
75 * Move crazyidea to this new revision, in which both sets of changes are applied.
77 You can do this by checking out the crazyidea branch and doing
78 [code]
79 $ git merge master
80 [/code]
82 Like rebase, merge may have to stop and ask you to resolve a conflict.
84 Unlike rebase, merge does not create an alternate version of history.
85 Instead, it "joins" the two branches into a new commit that shares both histories.
87 In this sense, a merge is kind of like the opposite of a branch.
89 You might think of a branch as allowing you to create an alternate universe.
90 In one universe, you spent the day building a swingset.
91 In the other, you repaired the roof.
92 At the end of the day, you can merge the two universes back into one universe in which you have a swingset and a roof that does not leak.
94 However, the merge only changes the branch you had checked out.
95 The master branch will not have your changes from the crazyidea branch.
96 Just remember, Git will only alter a branch if you have it checked out.