Branches¶
NOTE: using bash/git commands is not fully supported on jupyterlite yet (due to single thread/process restriction), and the cells below might error out on the browser (jupyterlite) version of this notebook
Branches are incredibly important to why git
is cool and powerful.
They are an easy and cheap way of making a second version of your software, which you work on in parallel, and pull in your changes when you are ready.
import os
top_dir = os.getcwd()
git_dir = os.path.join(top_dir, 'learning_git')
working_dir = os.path.join(git_dir, 'git_example')
os.chdir(working_dir)
%%bash
git branch # Tell me what branches exist
%%bash
git switch -c experiment # Make a new branch (use instead `checkout -b` if you have a version of git older than 2.23)
%%bash
git branch
%%writefile Wales.md
Mountains In Wales
==================
* Pen y Fan
* Tryfan
* Snowdon
* Glyder Fawr
* Fan y Big
* Cadair Idris
%%bash
git add Wales.md
git commit -m "Add Cadair Idris"
%%bash
git switch main # Switch to an existing branch (use `checkout` if you are using git older than 2.23)
%%bash
cat Wales.md
%%bash
git switch experiment
cat Wales.md
Publishing branches¶
To let the server know there's a new branch use:
%%bash
git push -u origin experiment
We use --set-upstream origin
(Abbreviation -u
) to tell git that this branch should be pushed to and pulled from origin per default.
If you are following along, you should be able to see your branch in the list of branches in GitHub.
Once you've used git push -u
once, you can push new changes to the branch with just a git push.
If others checkout your repository, they will be able to do git switch experiment
to see your branch content,
and collaborate with you in the branch.
%%bash
git branch -r
Local branches can be, but do not have to be, connected to remote branches
They are said to "track" remote branches. push -u
sets up the tracking relationship.
You can see the remote branch for each of your local branches if you ask for "verbose" output from git branch
:
%%bash
git branch -vv
Find out what is on a branch¶
In addition to using git diff
to compare to the state of a branch,
you can use git log
to look at lists of commits which are in a branch
and haven't been merged yet.
%%bash
git log main..experiment
Git uses various symbols to refer to sets of commits.
The double dot A..B
means "ancestor of B and not ancestor of A"
So in a purely linear sequence, it does what you'd expect.
%%bash
git log --graph --oneline HEAD~9..HEAD~5
But in cases where a history has branches, the definition in terms of ancestors is important.
%%bash
git log --graph --oneline HEAD~5..HEAD
If there are changes on both sides, like this:
%%bash
git switch main
%%writefile Scotland.md
Mountains In Scotland
==================
* Ben Eighe
* Cairngorm
* Aonach Eagach
%%bash
git diff Scotland.md
%%bash
git add Scotland.md
git commit -m "Commit Aonach onto main branch"
Then this notation is useful to show the content of what's on what branch:
%%bash
git log --left-right --oneline main...experiment
Three dots means "everything which is not a common ancestor" of the two commits, i.e. the differences between them.
Merging branches¶
We can merge branches, and just as we would pull in remote changes, there may or may not be conflicts.
%%bash
git branch
git merge experiment
%%bash
git log --graph --oneline HEAD~3..HEAD
Cleaning up after a branch¶
%%bash
git branch
%%bash
git branch -d experiment
%%bash
git branch
%%bash
git branch --remote
%%bash
git push --delete origin experiment
# Remove remote branch
# - also can use github interface
%%bash
git branch --remote
A good branch strategy¶
- A
develop
ormain
branch: for general new code - (the cutting edge version of your software) feature
branches: for specific new ideas. Normally branched out frommain
.release
branches: when you share code with users. A particular moment of thedevelop
process that it's considered stable.- Useful for including security and bug patches once it's been released.
- A
production
branch: code used for active work. Normally it's the same than the latest release.
Grab changes from a branch¶
Make some changes on one branch, switch back to another, and use:
git checkout <branch> <path>
to quickly grab a file from one branch into another. This will create a copy of the file as it exists in <branch>
into your current branch, overwriting it if it already existed.
For example, if you have been experimenting in a new branch but want to undo all your changes to a particular file (that is, restore the file to its version in the main
branch), you can do that with:
git checkout main test_file
Using git checkout
with a path takes the content of files.
To grab the content of a specific commit from another branch,
and apply it as a patch to your branch, use:
git cherry-pick <commit>