Outside of the given simple lifecycle of a feature branch git offers a lot more by way of information about commits and navigating between those commits and whilst you may use these commands less frequently they start to show you some of the power behind git. If you’re new to git here’s a quick explanation of two concepts that will help understand how to navigate between the tracked information inside git:
- Hashes:
Hashes are a 40 character string which represent a unique key relating to a specific commit, git can use these to verify commit contents and you can use them to reference individual commits. Throwing around 40 character long keys is unwieldy though so for mercy’s sake git will let you use a short code of only the first 7 characters. - Tags:
Tags are human-readable names associated with specific commits or hashes and can help simplify things an awful lot. In another post I’ll go through some of the more commonly used commands
Diff/Show
Sometimes things go wrong, or you’d just like to know more about the branches you’re working with or the progression between change sets on those branches, for a lot of those features we use either the diff or show command:
- show diff in code between two branches (verbose):
([any])$ git diff [Branch1(earlier)]..[Branch2(later)]
- show which files have changed between two branches:
([any])$ git diff --stat [Branch1(earlier)]..[Branch2(later)]
- compare file between two branches:
([any])$ git diff [Branch1(earlier)]..[Branch2(later)] [Filename]
- compare file between two commits:
([any])$ git diff [CommitHash1(earlier)]..[CommitHash2(later)] [Filename]
- show commits with hashes on current branch (small hash & msg only):
[Branchname])$ git log --oneline
- show commits with hashes on current branch since creation:
([Branchname])$ git log --oneline master...
- show commits with hashes on current branch (full hash & msg only):
([Branchname])$ git log --format=oneline
- show stats and summary of last commit:
([Branchname])$ git log --stat --summary -1
- verbose info
([Branchname])$ git log
- show branches on remote with hashes:
([Branchname])$ git ls-remote
- show fuller information on remote:
([any])$ git remote show origin
Stepping in and out
Being able to interrogate the differences between branches and commits is great but there are some things that comparing code changes won’t quickly give you (although a contentious developer would make relevant info available in the commit message!), one of which is how well code runs. For a more in depth look at a commit you can step between them, pulling all relevant files into your workspace. Before doing this we need to be aware of the following consequence of checking out a specific commit:
- Detached head state:
When you checkout a branch in git the head pointer indicates that branch and latest commit, loading the associated files into your working directory, and is automatically moved on when a new commit is made. The detached head state arises when you checkout a specific commit (and load the associated files) as any changes made do not belong to a branch and can be easily lost (they will be orphaned when you switch back to an established branch and deleted). One way of saving these changes would be to pull them into a new branch with:$ git checkout -b [BranchName]
or to revert back to a valid branch simply check one out with:
$ git checkout [BranchName]
Understanding this enables us to make use of the following commands to jump around:
- Get a list of recent commits:
([Branchname])$ git log --oneline
- Temporarily go to different commit via hash or short hash:
([Branchname])$ git checkout [CommitHash]
- Temporarily go to different commit via tag:
([Branchname])$ git checkout tags/[Tag]
Branch admin
With a fuller understanding of which changes are held where you may find that you can make some changes to your branches, here are some commands to help with that:
- Rename current branch:
([Branchname])$ git branch -m [NewBranchName]
- Rename another branch:
([Branchname])$ git branch -m [OldBranchName] [NewBranchName]
- Delete branch, the latter being shorthand for –delete –force, use with care!:
([master])$ git branch -d [BranchName] ([master])$ git branch -D [BranchName]
- Push deletion of local to remote:
([master])$ git push origin :[BranchName]
- Delete remote branch only:
([master])$ git push origin --delete [BranchName]
- Revert branch to previous commit, preserving all intermediate commit information:
[Branchname])$ git revert [CommitHash]