You are here: Home » NewsFeeds » Git Tips

Git Tips

I’ve been using git full time for the past 4 years, and I wanted to share the most practical tips that I’ve learned along the way. Hopefully, it will be useful to somebody out there.

If you are completely new to git, I suggest reading Git Cheat Sheet first or checking out this free tutorial. This article is aimed at somebody who has been using git for three months or more.

Table of Contexts:

  1. Parameters for better logging
    git log --oneline --graph
  2. Log actual changes in a file
    git log -p filename
  3. Only Log changes for some specific lines in file
    git log -L 1,1:some-file.txt
  4. Log changes not yet merged to the parent branch
    git log --no-merges master..
  5. Extract a file from another branch
    git show some-branch:some-file.js
  6. Some notes on rebasing
    git pull --rebase
  7. Remember the branch structure after a local merge
    git merge --no-ff
  8. Fix your previous commit, instead of making a new commit
    git commit --amend
  9. Three stages in git, and how to move between them
    git reset --hard HEAD and git status -s
  10. Revert a commit, softly
    git revert -n
  11. See diff-erence for the entire project (not just one file at a time) in a 3rd party diff tool
    git difftool -d
  12. Ignore the white space
    git diff -w
  13. Only “add” some changes from a file
    git add -p
  14. Discover and zap those old branches
    git branch -a
  15. Stash only some files
    git stash -p
  16. Good commit messages
  17. Git Auto-completion
  18. Create aliases for your most frequently used commands
  19. Quickly find a commit that broke your feature (EXTRA AWESOME)
    git bisect

1. Parameters for better logging

Sample Command git log --oneline --graph

Chances are, by now you’ve used git log. It supports a number of command line parameters, which are very powerful, especially when used in combination. Here are the ones that I use the most:

  • --author=“Alex Kras" – Only show commits made by a certain author
  • --name-only – Only show names of files that changed
  • --oneline – Show commit data compressed to one line
  • --graph – Show dependency tree for all commits
  • --reverse – Show commits in reverse order (Oldest commit first)
  • --after – Show all commits that happened after certain date
  • --before – Show all commits that happened before certain data

For example, I once had a manager who required weekly reports submitted each Friday. So every Friday I would just run: git log --author="Alex Kras" --after="1 week ago" --oneline, edit it a little and send it in to the manager for review.

Git has a lot more command line parameters that are handy. Just run man git log and see what it can do for you.

If everything else fails, git has a --pretty parameter that let’s you create a highly customizable output.

git-log-oneline

2. Log actual changes in a file

Sample Command git log -p filename

git log -p or git log -p filename lets you view not only the commit message, author, and date, but actual changes that took place in each commit.

Then you can use the regular less search command of “slash” followed by your search term/{{your-search-here}} to look for changes to a particular keyword over time. (Use lower case n to go to the next result, and upper case N to go to the previous result).

git-log-search

3. Only Log changes for some specific lines in a file

Sample Command git log -L 1,1:some-file.txt

You can use git blame filename to find the person responsible for every line of the file.

git-blame

git blame is a great tool, but sometimes it does not provide enough information.

An alternative is provided by git log with a -L flag. This flag allows you to specify particular lines in a file that you are interested in. Then Git would only log changes relevant to those lines. It’s kind of like git log -p with focus.

git log -L 1,1:some-file.txt

git-log-lines

4. Log changes not yet merged to the parent branch

Sample: git log --no-merges master..

If you ever worked on a long-lived branches, with multiple people working on it, chances are you’ve experienced numerous merges of the parent branch(i.e. master) into your feature branch. This makes it hard to see the changes that took place on the master branch vs. the changes that have been committed on the feature branch and which have yet to be merged.

git log --no-merges master.. will solve the issue. Note the --no-merges flag indicate to only show changes that have not been merged yet to ANY branch, and the master.. option, indicates to only show changes that have not been merged to master branch. (You must include the .. after master).

You can also do git show --no-merges master.. or git log -p --no-merges master.. (output is identical) to see actual file changes that are have yet to be merged.

5. Extract a file from another branch

Sample: git show some-branch:some-file.js

Sometimes it is nice to take a pick at an entire file on a different branch, without switching to this branch.

You can do so via git show some-branch-name:some-file-name.js, which would show the file in your terminal.

You can also redirect the output to a temporary file, so you can perhaps open it up in a side by side view in your editor of choice.

git show some-branch-name:some-file-name.js > deleteme.js

Note: If all you want to see is a diff between two files, you can simple run:
git diff some-branch some-filename.js

6. Some notes on rebasing

Sample: git pull -—rebase

We’ve talked about a lot of merge commits when working on a remote branch. Some of those commits can be avoided by using git rebase.

Generally I consider rebasing to be an advanced feature, and it’s probably best left for another post.

Even git book has the following to say about rebasing.

Ahh, but the bliss of rebasing isn’t without its drawbacks, which can be summed up in a single line:

Do not rebase commits that exist outside your repository

If you follow that guideline, you’ll be fine. > If you don’t, people will hate you, and you’ll be scorned by friends and family.

https://git-scm.com/book/en/v2/Git-Branching-Rebasing#The-Perils-of-Rebasing

That being said, rebasing is not something to be afraid of either, rather something that you should do with care.

Probably the best way to rebase is using interactive rebasing, invoked via git rebase -i {{some commit hash}}. It will open up an editor, with self explanatory instruction. Since rebasing is outside of the scope of this article, I’ll leave it at that.

git-rebase-i

One particular rebase that is very helpful is git pull --rebase.

For example, imagine you are working on a local version of a master branch, and you made one small commit. At the same time, somebody else checked in a week worth of work onto the master branch. When you try to push your change, git tells you to do a git pull first, to resolve the conflict. Being a good citizen that you are, you do a git pull to end up with the following commit message auto generated by git.

Merge remote-tracking branch ‘origin/master’

While this is not a big deal and is completely safe, it does clutter log history a bit.

In this case, a valid alternative is to do a git pull --rebase instead.

This will force git to first pull the changes, and then re-apply(rebase) your un-pushed commits on top of the latest version of the remote branch, as if they just took place. This will remove the need for merge and the ugly merge message.

7. Remember the branch structure after a local merge

Sample: git merge --no-ff

I like to create a new branch for every new bug or feature. Among other benefits, it helps me to get a great clarity on how a series of commits may relate to a particular task. If you ever merged a pull request on github or a similar tool, you will in fact be able to nicely see the merged branch history in git log --oneline --graph view.

If you ever try to merge a local branch, into another local branch, you may notice git has flatten out the branch, making it show up as a straight line in git history.

If you want to force git to keep branches history, similarly to what you would see during a pull request, you can add a --no-ff flag, resulting in a nice commit history tree.

git merge --no-ff some-branch-name

git-merge-no-ff

8. Fix your previous commit, instead of making a new commit

Sample git commit --amend

This one is pretty straightforward.

Let say you made a commit and then realized you made a typo. You could make a new commit with a “descriptive” message typo. But there is a better way.

If you haven’t pushed to the remote branch yet, you can simply do the following:

  1. Fix your typo
  2. Stage the newly fixed file via git add some-fixed-file.js
  3. Run git commit --amend which would add the most recent changes to your latest commit. It will also give you a chance to edit the commit message.
  4. Push the clean branch to remote, when ready

git-commit-amend

If you are working on your own branch, you can fix commits even after you have pushed, you would just have to do a git push -f (-f stands for force), which would over-ride the history. But you WOULD NOT want to do this on a branch that is being used by other people (as discussed in rebase section above). At that point, a “typo” commit, might be your best bet.

9. Three stages in git, and how to move between them

Sample git reset --hard HEAD and git status -s

As you may already know by now, a file in git can be in 3 stages:
1. Not staged for commit
2. Staged for commit
3. Committed

You can see a long description of the files and state they are in by running git status. You move a file from “not staged for commit” stage to “staged for commit” stage, by running git add filename.js or git add . to add all files at once.

Another view that makes it much easier to visualize the stages is invoked via git status -s where -s stand for short (I think), and would result in an output that looks like that:

git-stages

Obviously, git status will not show files that have already been committed, you can use git log to see those instead


 

Original article