- Chapter 5 Branches
A new branch is a new development environment with an isolated working directory, staging and project history.
‘git branch’ is used for listing, creating, and deleting branches.
To view existing branches,
$ git branch
The output will indicate the currently checkedout branch with an asterisk.
The master branch is git’s default branch.
Create a new branch,
$ git branch <branch-name>
This does not switch you to the new branch, only creates a pointer to the current HEAD. (but I thought HEAD was the current commit!)
To switch branch,
$ git checkout <branch-name>
Initially both branches reference the same commit, but any new commits will be exclusive to the current branch and so each branch will have a HEAD of its own.
To delete a branch,
$ git branch -d <branch-name>
This will not delete branches with unmerged conflicts, to force the deletion,
$ git branch -D <branch-name>
After switching to a new branch, your working directory is updated to match the specified branche’s commit. (I think this just means, the latest commit or HEAD will be on this branch. Isn’t that obvious, since the HEAD is another name for the latest commit? Or maybe the HEAD is always the latest commit, but will take it from the checked out branch.)
Make sure your working directory is ‘clean’, meaning no uncommitted changes, before checking out another branch. Otherwise ‘git checkout’ could overwrite your modifications.
Using ‘git checkout’ with tags and commit IDs puts you in a detached HEAD state. his means you are not on a branch anymore, you are directly viewing a commit and will lose all work as soon as you switch to a real branch.
Creating a new branch in a detached HEAD state,
$ git checkout -b <new-branch-name>
This is a new branch reference to the formerly detached state.
In this case ‘-b’ is a shortcut for the two commands,
$ git branch <new-branch-name>
$ git checkout <new-branch-name>
(But how do you use ‘git checkout’ with tags and commit IDs to create a detached HEAD state.)
Merging is the process of pulling commits from one branch into another.
Merge methodologies: “fast-forward” merge, or a “3-way” merge.
The branch you want to merge into must be checked out and the target branch will remain unchanged.
To merge a branch called ‘sidebranch’ in master,
$ git checkout master
$ git merge sidebranch
This leaves sidebranch unchanged.
“fast-forward” merge: I create a new branch off master and add two commits to it, this type of merge syncs master with that latest branch commit. Master then contains all desired history and the branch can be deleted.
This was a simple situation because there were no extra commits on the master. If there are use a “3-way” merge.
“3-way” merge: I create a new branch off master and add two commits, during which time the master gets a new commit. To merge git generates a new merge commit, a combined snapshot of both branches. This commit has two parents commits and a history from both branches.
$ git checkout master
both types of merge use the same command,
$ git merge sidebranch
Two branches that make different changes to the same code portion is a merge conflict. This can not occur in a “fast-forward” merge.
When a merge conflict occurs use,
$ git status
If you get a merge conflict open the file and you’ll see something like,
This content is from the current branch.
This is a conflicting change from another branch.
Delete the content you don’t want including all of the <<<<<< , ======= , >>>>>>> lines also.
$ git add <file>
$ git commit
Rebasing requires a branch to be checked out,
$ git checkout branch
Then to move the entire branch onto the tip of master,
$ git rebase master (but what happens to the branch then?)
This results in the same snapshot as if branch was merged with master.
“3-way” merge results in an extra merge commit. Rebasing has no extra commits and results in a cleaner linear history.
Change commits as you’re moving them to the new base, by specifying an interactive rebase,
$ git rebase -i master
This populates an editor with commits from the branch.
Specify an interactive rebase as follows,
pick 58dec2a First commit for new feature
squash 6ac8a9f Second commit for new feature
‘pick’ moves the first commit to the new base just as in ‘git rebase’. ‘squash’ combines the second commit with the previous one, so you end up with one commit containing all the changes.
Interactive rebasing lets you rewrite a branches history, you can add intermediate commits, then go back and fix them into more meaningful progression afterwards.
never rebase a branch that has been pushed to a public repository