You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: en/book/03-git-branching/chapter3.asc
+76-52Lines changed: 76 additions & 52 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,5 @@
1
+
**TODO**: reword figure titles
2
+
1
3
== Git Branching
2
4
3
5
Nearly every VCS has some form of branching support. Branching means you diverge from the main line of development and continue to do work without messing with that main line. In many VCS tools, this is a somewhat expensive process, often requiring you to create a new copy of your source code directory, which can take a long time for large projects.
@@ -271,7 +273,7 @@ It’s worth pointing out that Git determines the best common ancestor to use fo
271
273
.Git automatically creates a new commit object that contains the merged work
272
274
image::images/18333fig0317-tn.png[Git automatically creates a new commit object that contains the merged work.]
273
275
274
-
Now that your work is merged in, you have no further need for the `iss53` branch. You can delete it and then close the ticket in your ticket-tracking system:
276
+
Now that your work is merged in, you have no further need for the `iss53` branch. You can close the ticket in your ticket-tracking system, and delete the branch:
275
277
276
278
[source,shell]
277
279
----
@@ -295,19 +297,21 @@ Git hasn’t automatically created a new merge commit. It has paused the process
295
297
[source,shell]
296
298
----
297
299
[master*]$ git status
298
-
index.html: needs merge
299
-
# On branch master
300
-
# Changed but not updated:
301
-
# (use "git add <file>..." to update what will be committed)
302
-
# (use "git checkout -- <file>..." to discard changes in working directory)
303
-
#
304
-
# unmerged: index.html
305
-
#
300
+
On branch master
301
+
You have unmerged paths.
302
+
(fix conflicts and run "git commit")
303
+
304
+
Unmerged paths:
305
+
(use "git add <file>..." to mark resolution)
306
+
307
+
both modified: index.html
308
+
309
+
no changes added to commit (use "git add" and/or "git commit -a")
306
310
----
307
311
308
312
Anything that has merge conflicts and hasn’t been resolved is listed as unmerged. Git adds standard conflict-resolution markers to the files that have conflicts, so you can open them manually and resolve those conflicts. Your file contains a section that looks something like this:
@@ -318,9 +322,9 @@ Anything that has merge conflicts and hasn’t been resolved is listed as unmerg
318
322
>>>>>>> iss53:index.html
319
323
----
320
324
321
-
This means the version in HEAD (your master branch, because that was what you had checked out when you ran your merge command) is the top part of that block (everything above the `=======`), while the version in your `iss53` branch looks like everything in the bottom part. In order to resolve the conflict, you have to either choose one side or the other or merge the contents yourself. For instance, you might resolve this conflict by replacing the entire block with this:
325
+
This means the version in `HEAD` (your `master` branch, because that was what you had checked out when you ran your merge command) is the top part of that block (everything above the `=======`), while the version in your `iss53` branch looks like everything in the bottom part. In order to resolve the conflict, you have to either choose one side or the other or merge the contents yourself. For instance, you might resolve this conflict by replacing the entire block with this:
Hit return to start merge resolution tool (opendiff):
343
352
----
344
353
345
-
If you want to use a merge tool other than the default (Git chose `opendiff` for me in this case because I ran the command on a Mac), you can see all the supported tools listed at the top after ``merge tool candidates''. Type the name of the tool you’d rather use. In <<_git_tools>>, we’ll discuss how you can change this default value for your environment.
354
+
If you want to use a merge tool other than the default (Git chose `opendiff` for me in this case because I ran the command on a Mac), you can see all the supported tools listed at the top after ``one of the following tools.'' Just type the name of the tool you’d rather use. In <<_git_tools>>, we’ll discuss how you can change this default value for your environment (Git gave us a helpful hint).
346
355
347
356
After you exit the merge tool, Git asks you if the merge was successful. If you tell the script that it was, it stages the file to mark it as resolved for you.
348
357
@@ -351,12 +360,13 @@ You can run `git status` again to verify that all conflicts have been resolved:
351
360
[source,shell]
352
361
----
353
362
$ git status
354
-
# On branch master
355
-
# Changes to be committed:
356
-
# (use "git reset HEAD <file>..." to unstage)
357
-
#
358
-
# modified: index.html
359
-
#
363
+
On branch master
364
+
All conflicts fixed but you are still merging.
365
+
(use "git commit" to conclude merge)
366
+
367
+
Changes to be committed:
368
+
369
+
modified: index.html
360
370
----
361
371
362
372
If you’re happy with that, and you verify that everything that had conflicts has been staged, you can type `git commit` to finalize the merge commit. The commit message by default looks something like this:
@@ -365,21 +375,34 @@ If you’re happy with that, and you verify that everything that had conflicts h
365
375
----
366
376
Merge branch 'iss53'
367
377
368
-
369
378
Conflicts:
370
-
index.html
379
+
index.html
371
380
#
372
-
# It looks like you may be committing a MERGE.
381
+
# It looks like you may be committing a merge.
373
382
# If this is not correct, please remove the file
374
-
#.git/MERGE_HEAD
383
+
#.git/MERGE_HEAD
375
384
# and try again.
385
+
386
+
387
+
# Please enter the commit message for your changes. Lines starting
388
+
# with '#' will be ignored, and an empty message aborts the commit.
389
+
# On branch master
390
+
# All conflicts fixed but you are still merging.
391
+
#
392
+
# Changes to be committed:
393
+
# modified: index.html
376
394
#
377
395
----
378
396
379
397
You can modify that message with details about how you resolved the merge if you think it would be helpful to others looking at this merge in the future – why you did what you did, if it’s not obvious.
380
398
381
399
==== Undoing Merges
382
400
401
+
**TODO**
402
+
403
+
- `git reset --merge ORIG_HEAD`
404
+
- `git revert -m 1 sha`
405
+
383
406
=== Branch Management
384
407
385
408
Now that you’ve created, merged, and deleted some branches, let’s look at some branch-management tools that will come in handy when you begin using branches all the time.
@@ -389,27 +412,27 @@ The `git branch` command does more than just create and delete branches. If you
389
412
[source,shell]
390
413
----
391
414
$ git branch
392
-
iss53
415
+
iss53
393
416
* master
394
-
testing
417
+
testing
395
418
----
396
419
397
420
Notice the `*` character that prefixes the `master` branch: it indicates the branch that you currently have checked out. This means that if you commit at this point, the `master` branch will be moved forward with your new work. To see the last commit on each branch, you can run `git branch -v`:
398
421
399
422
[source,shell]
400
423
----
401
424
$ git branch -v
402
-
iss53 93b412c fix javascript issue
425
+
iss53 93b412c fix javascript issue
403
426
* master 7a98805 Merge branch 'iss53'
404
-
testing 782fd34 add scott to the author list in the readmes
427
+
testing 782fd34 add scott to the author list in the readmes
405
428
----
406
429
407
430
Another useful option to figure out what state your branches are in is to filter this list to branches that you have or have not yet merged into the branch you’re currently on. The useful `--merged` and `--no-merged` options have been available in Git since version 1.5.6 for this purpose. To see which branches are already merged into the branch you’re on, you can run `git branch --merged`:
408
431
409
432
[source,shell]
410
433
----
411
434
$ git branch --merged
412
-
iss53
435
+
iss53
413
436
* master
414
437
----
415
438
@@ -420,15 +443,15 @@ To see all the branches that contain work you haven’t yet merged in, you can r
420
443
[source,shell]
421
444
----
422
445
$ git branch --no-merged
423
-
testing
446
+
testing
424
447
----
425
448
426
449
This shows your other branch. Because it contains work that isn’t merged in yet, trying to delete it with `git branch -d` will fail:
427
450
428
451
[source,shell]
429
452
----
430
453
$ git branch -d testing
431
-
error: The branch 'testing' is not an ancestor of your current HEAD.
454
+
error: The branch 'testing' is not fully merged.
432
455
If you are sure you want to delete it, run 'git branch -D testing'.
433
456
----
434
457
@@ -518,12 +541,13 @@ If you have a branch named `serverfix` that you want to work on with others, you
This is a bit of a shortcut. Git automatically expands the `serverfix` branchname out to `refs/heads/serverfix:refs/heads/serverfix`, which means, ``Take my serverfix local branch and push it to update the remote’s serverfix branch.'' We’ll go over the `refs/heads/` part in detail in <<_git_internals>>, but you can generally leave it off. You can also do `git push origin serverfix:serverfix`, which does the same thing – it says, ``Take my serverfix and make it the remote’s serverfix.'' You can use this format to push a local branch into a remote branch that is named differently. If you didn’t want it to be called `serverfix` on the remote, you could instead run `git push origin serverfix:awesomebranch` to push your local `serverfix` branch to the `awesomebranch` branch on the remote project.
@@ -533,12 +557,12 @@ The next time one of your collaborators fetches from the server, they will get a
It’s important to note that when you do a fetch that brings down new remote branches, you don’t automatically have local, editable copies of them. In other words, in this case, you don’t have a new `serverfix` branch – you only have an `origin/serverfix` pointer that you can’t modify.
@@ -548,8 +572,8 @@ To merge this work into your current working branch, you can run `git merge orig
548
572
[source,shell]
549
573
----
550
574
$ git checkout -b serverfix origin/serverfix
551
-
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
552
-
Switched to a new branch "serverfix"
575
+
Branch serverfix set up to track remote branch serverfix from origin.
576
+
Switched to a new branch 'serverfix'
553
577
----
554
578
555
579
This gives you a local branch that you can work on that starts where `origin/serverfix` is.
@@ -558,22 +582,22 @@ This gives you a local branch that you can work on that starts where `origin/ser
558
582
559
583
Checking out a local branch from a remote branch automatically creates what is called a _tracking branch_. Tracking branches are local branches that have a direct relationship to a remote branch. If you’re on a tracking branch and type `git push`, Git automatically knows which server and branch to push to. Also, running `git pull` while on one of these branches fetches all the remote references and then automatically merges in the corresponding remote branch.
560
584
561
-
When you clone a repository, it generally automatically creates a `master` branch that tracks `origin/master`. That’s why `git push` and `git pull` work out of the box with no other arguments. However, you can set up other tracking branches if you wish – ones that don’t track branches on `origin` and don’t track the `master` branch. The simple case is the example you just saw, running `git checkout -b [branch] [remotename]/[branch]`. If you have Git version 1.6.2 or later, you can also use the `--track` shorthand:
585
+
When you clone a repository, it generally automatically creates a `master` branch that tracks `origin/master`. That’s why `git push` and `git pull` work out of the box with no other arguments. However, you can set up other tracking branches if you wish – ones that track branches on other remotes, or don’t track the `master` branch. The simple case is the example you just saw, running `git checkout -b [branch] [remotename]/[branch]`. If you have Git version 1.6.2 or later, you can also use the `--track` shorthand:
562
586
563
587
[source,shell]
564
588
----
565
589
$ git checkout --track origin/serverfix
566
-
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
567
-
Switched to a new branch "serverfix"
590
+
Branch serverfix set up to track remote branch serverfix from origin.
591
+
Switched to a new branch 'serverfix'
568
592
----
569
593
570
594
To set up a local branch with a different name than the remote branch, you can easily use the first version with a different local branch name:
571
595
572
596
[source,shell]
573
597
----
574
598
$ git checkout -b sf origin/serverfix
575
-
Branch sf set up to track remote branch refs/remotes/origin/serverfix.
576
-
Switched to a new branch "sf"
599
+
Branch sf set up to track remote branch serverfix from origin.
600
+
Switched to a new branch 'sf'
577
601
----
578
602
579
603
Now, your local branch sf will automatically push to and pull from origin/serverfix.
@@ -586,7 +610,7 @@ Suppose you’re done with a remote branch – say, you and your collaborators a
Boom. No more branch on your server. You may want to dog-ear this page, because you’ll need that command, and you’ll likely forget the syntax. A way to remember this command is by recalling the `git push [remotename] [localbranch]:[remotebranch]` syntax that we went over a bit earlier. If you leave off the `[localbranch]` portion, then you’re basically saying, ``Take nothing on my side and make it be `[remotebranch]`.''
0 commit comments