Git Branching What is a branch?

Git Branching
What is a branch?
Review: Distributed - Snapshots
Files are stored by SHA-1 hash rather than filename
Stored in git database in compressed format
Must “checkout” from database into working directory to edit
In this example, files A, B and C are tracked
Example commit, 3 files
After 3 commits
Default branch is master
master moves forward automatically when you commit
Add a branch
cmd: git branch testing
Why is creating a branch in git cheap and quick? Because it’s just creating a
40-character SHA-1 checksum of the commit it points to
But you’re still on master
HEAD = pointer to current branch
NOTE: concept of HEAD is different from CVS
Use checkout to change
cmd: git checkout testing
Make changes on that branch
edit test.rb (e.g., vim test.rb)
cmd: git commit –a –m ‘made a change’
Switch back to master
cmd: git checkout master
NOTE: This also reverts files in your working directory (e.g., c:\mycode) back
to master.
So edit to test.rb no longer in your working directory (but you haven’t lost it, as
long as you committed before switching – remember it will be in your local
database. But don’t delete .git!)
Change master branch
edit test.rb again
cmd: git commit –a –m ‘made other changes’
Example






Steps (for future reference)
Create Java Project
Create class TheBrancher,
including main
git init
git add src/*
git commit -m "Initial load"
Updated source with a "leaf" variable

public class TheBrancher {
private String theLeaf;
public void updateLeaf(String newLeaf) {
theLeaf = newLeaf;
}
public void showLeaf() {
System.out.println(theLeaf);
}
public static void main(String[] args) {
TheBrancher brancher = new TheBrancher();
brancher.updateLeaf("Turning yellow for fall");
brancher.showLeaf();
}
}
Example, continued

git commit -am "added a leaf"
private String theTree;

git log –graph –decorate --oneline
public void makeATree() {

# create a branch

git branch needTree

# see the branch

git branch

# switch to new branch

git checkout needTree
theTree = "Aspen";
}
@Override
public String toString() {
return "TheBrancher [theLeaf=" + theLeaf + ",
theTree=" + theTree + "]";
}
# and in main
brancher.makeATree();
System.out.println(brancher);


git commit -am "Added a tree"

git status

# go back to master

git checkout master

# what happened in Eclipse?
Basic Merging
No conflicts
A branch/merge example
Start with master branch
cmd: git checkout –b iss53
NOTE: This creates branch and switches to it
Update branch
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
Need to switch to an urgent fix
git checkout master
git checkout –b hotfix
vim index.html
git commit –a –m ‘fixed broken code’
NOTE: git won’t let you switch to master if you have uncommitted changes that
conflict with the code you’re checking out. So you should have a clean slate before
you switch (stash and amend can deal with this – later topics)
Now merge hotfix and master
git checkout master
git merge hotfix
This will be a “fast forward” merge – because branch was directly
upstream, git just moves pointer forward.
A little cleanup, then return to issue 53
git branch –d hotfix
git checkout iss53
vim index.html
git commit –a –m ‘finished footer’
Be careful with branch –d. OK in this example, just a duplicate pointer. May
not always be the case.
Note that work done on hotfix is not part of iss53 branch.
Basic merge
$ git checkout master
$ git merge iss53
Merge made by recursive.
README | 1 +
1 files changed, 1 insertions(+), 0
deletions(-)
git identifies the best common ancestor to use for merge
Basic Merge result
master now includes hotfix and iss53
Remove iss53 if you want: git branch –d iss53
Remote Branches
Supplemental Material
Remote Branches


All the branching we’ve done so far has been local
Remote repositories (e.g., github) also have branches
Understanding remote branches
Git server – it’s not always
github!
right now, only have master
clone files from server into
your working directory.
Remote branch – on server –
[remote]/[branch]
clone names your remote
origin by default
Local branch – [branch]
Branches diverging
You’ve made changes.
Someone else pushed
changes.
master on remote NOT
the same as your
master!
BUT, both are master
(we’re not dealing with
local branches yet)
Synchronize your work
note: fetch doesn’t merge!
Need to:
git fetch origin
git merge origin/master
(handle conflicts if any, note
that branch name is
origin/master)
git push
You can also do:
git pull origin master
(does fetch and merge)
Tracking Branch





A tracking branch is a local branch that has a direct
relation to a remote branch
If you’re on a tracking branch and type git push, Git
knows which server and branch to push to
git pull on a tracking branch fetches remote references
and merges
clone automatically creates a master branch that tracks
origin/master. So git push and git pull work right out of
the box.
You can add other tracking branches: git checkout --track
Forking


If you want to contribute to a project but don’t have push
access, you can do a fork… create your own copy.
Main project can pull in those changes later by adding
them as remotes and merging in the code from the fork.
Configuration




It’s a good idea to set up your .gitignore file
A global file (.gitignore_global) can also be very useful for
ignoring files in every git repositories on your computer.
Local per-repository rules can be added to the
.git/info/exclude file in your repository
Example for Java:
*.class
# Package Files #
*.jar
*.war
*.ear
Be sure to read! : https://help.github.com/articles/ignoring-files
More useful info
http://stackoverflow.com/questions/8358035/whats-the-difference-between-git-revertcheckout-and-reset
These three commands have entirely different purposes. They are not even remotely
similar.
git revert
This command creates a new commit that undoes the changes from a previous
commit. This command adds new history to the project (it doesn't modify existing
history).
git checkout
This command checks-out content from the repository and puts it in your work tree.
It can also have other effects, depending on how the command was invoked. For
instance, it can also change which branch you are currently working on. This command
doesn't make any changes to the history.
git reset
This command is a little more complicated. It actually does a couple of different things
depending on how it is invoked. It modifies the index (the so-called "staging area"). Or
it changes what commit a branch head is currently pointing at. This command may alter
history (by changing the commit that a branch references).
Continued…

Using these commands

If a commit has been made somewhere in the project's history, and you later decide
that the commit is wrong and should not have been done, then git revert is the tool
for the job. It will undo the changes introduced by the bad commit, recording the
"undo" in the history.

If you have modified a file in your working tree, but haven't committed the change,
then you can use git checkout to checkout a fresh-from-repository copy of the file.

If you have made a commit, but haven't shared it with anyone else and you decide
you don't want it, then you can use git reset to rewrite the history so that it looks
as though you never made that commit.

These are just some of the possible usage scenarios. There are other commands
that can be useful in some situations, and the above three commands have other
uses as well.