-
Notifications
You must be signed in to change notification settings - Fork 701
Useful Git Commands
This is a page to keep a list of helpful git commands and git-related tips.
NOTE: Many of these options can be used in combination! If you note two different options for git log
, for example, it's likely they can be used together. In addition, flags for different commands might be compatible if they achieve similar things: for example, many flags which are valid for git diff
and git log
can also be used with git show
.
- git stash
- Temporarily "stash away" your changes for later recovery
- Setting up an SSH key
- Avoid having to type your password every time you clone, push, or pull
- git diff -w
- Ignore whitespace changes when looking at a diff
- git log --since
- See the log of changes since a certain date or commit
- git commit --amend
- To easily make a change to the last commit
- git var -l
- To see information about the current repository and git settings
- git show [hash]
- To show the log message and the text diff for a given commit.
- git diff --name-status
- To see an SVN-style list of changed files
One of the big conveniences of git is the ease with which you can create and switch between different branches. However, it's not always convenient to check out a branch while you're currently working on changes in another branch. While you could commit those changes, you might not always want to if they are in an incomplete state. This is where git stash comes in!
Say you have made some changes to a couple files while on a branch:
$ git status
On branch more_git_updates
Your branch is up-to-date with 'origin/more_git_updates'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: Registry/Registry.EM_COMMON
In the middle of your changes, you want to view the state of the master branch. You could commit your changes to this branch and then switch to the master, but if your changes are incomplete and won't compile, that's often not desirable. To temporarily stash your changes away, use git stash
:
$ git stash
Saved working directory and index state WIP on more_git_updates: 41430b3 Per feedback from Negin Sobhani, reducing the number of .gitignore files by adding *.f90 rule to top-level .gitignore, then adding exceptions in external/.gitignore and var/.gitignore.
HEAD is now at 41430b3 Per feedback from Negin Sobhani, reducing the number of .gitignore files by adding *.f90 rule to top-level .gitignore, then adding exceptions in external/.gitignore and var/.gitignore.
Now running git status
will no longer show your changes:
$ git status
On branch more_git_updates
Your branch is up-to-date with 'origin/more_git_updates'.
nothing to commit, working tree clean
You can now check out a different branch, see what you need to see, and come back.
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
...
...
$ git checkout more_git_updates
Switched to branch 'more_git_updates'
Your branch is up-to-date with 'origin/more_git_updates'.
To see a list of stashed changes, use git stash list
git stash list
stash@{0}: WIP on more_git_updates: 41430b3 Per feedback from Negin Sobhani, reducing the number of .gitignore files by adding *.f90 rule to top-level .gitignore, then adding exceptions in external/.gitignore and var/.gitignore.
If you have stashed more than one change, more than one line will be listed here. In this case, there is only one, so git stash apply
will give us back our changes, and will automatically show us a git status
output to show us what our working directory now looks like:
$ git stash apply
On branch more_git_updates
Your branch is up-to-date with 'origin/more_git_updates'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: Registry/Registry.EM_COMMON
no changes added to commit (use "git add" and/or "git commit -a")
Since the changes were successfully applied, it's a good idea to delete the old stash before continuing your work:
$ git stash drop
Dropped refs/stash@{0} (e7a3e42a42bcfbd4d2f050ee03c156149d45e085)
You can now get back to work on your changes as normal.
There are other situations where git stash
might be useful, but I'd recommend using it sparingly and cautiously, as the stashed work does not become a permanent part of your repository: you can't push it or pull it anywhere, and it doesn't show up in logs or diffs. For more info, see the git documentation page: https://git-scm.com/docs/git-stash
Setting up an SSH key with your Github account allows you to clone, push, and pull code without having to enter your password every time. This can be very convenient, especially if you do github functions with scripts. It is machine-specific, so you must set up a different SSH key for every different machine you plan to work on.
To check if you already have an SSH key set up on your machine, issue the command ls ~/.ssh/id*pub
. If there are files with this naming convention found, you probably already have an SSH key set up!
If you already have an SSH key set up on your machine, you can skip to step 3! Otherwise, go to step 2 to set one up.
There are good instructions on creating an SSH key at this page. No need for me to copy it!
Again, Github already has some good instructions on doing this at this page.
After adding the SSH key to your account, you will no longer be prompted for your password when cloning, pushing, or pulling code on this machine. Remember you'll have to do this process individually for each machine you want to use SSH for.
Often (for me, at least), people make whitespace changes to files. For example, when fixing the indenting of some old code, or changing tabs (ugh) to spaces as is standard in the WRF code. However, when this is in combination with other, actually important changes, sometimes we just want to see code that changed when looking at a diff. You can achieve this with the "-w" flag:
git diff -w master
This flag can also be used with git show
!
git show -w
Note that not all whitespace changes will be ignored: if you insert or delete a new line that consists entirely of whitespace, or combine two lines that used to be separate, those changes will still appear
A lot of times we just want to see the log since a certain time or commit. This is easy to do with the "since" option in git log:
git log --since=YYYY-MM-DD
If you don't specify a time, git defaults to the last second of the day (so the list of commits it gives you will generally start after that day). If you'd rather get a different behavior, you can also specify the time:
git log --since="YYYY-MM-DD hh:mm:ss"
In addition, if you know a commit hash, you can specify that hash to see all the commits that have happened since then:
git log --since=abcd1234
A common problem in version control is realizing you made a mistake in the last commit. For example, let's say I make a commit to add some new options in var/README.namelist. To do so, I make the changes, use git add
to stage them, and commit them.
> vi var/README.namelist
> git add var/README.namelist
> git commit
> git commit
[fix-some-stuff 53cbf76] Added a few lines for new WRFDA options in var/README.namelist (ep_para_read and rden_bin)
1 file changed, 2 insertions(+), 2 deletions(-)
However, after I made the commit, I realized I forgot one of the new options. Luckily, with the git commit --amend
option, there's no need for me to have two commits for the same change! I just edit the file again, stage it again (with git add
), and use the magic of git commit --amend
to "amend" my new changes to the previous commit.
> vi var/README.namelist
> git add var/README.namelist
> git commit --amend
By default your original message will appear, but you can edit it! In this case, I'm going to add mention of the new variable that I forgot.
> git commit --amend
[fix-some-stuff bc35534] Added a few lines for new WRFDA options in var/README.namelist (ep_para_read, rden_bin, and use_4denvar)
Date: Thu Oct 27 21:12:18 2016 -0600
1 file changed, 3 insertions(+), 3 deletions(-)
After I save and quit, I will see the updated log message on the screen. When I do a git log, I will see a single commit with both sets of changes I made!
> git log
commit bc3553488d0021117f2d1414feafd4ef0529caee
Author: Michael Kavulich <kavulich@ucar.edu>
Date: Thu Oct 27 21:12:18 2016 -0600
Added a few lines for new WRFDA options in var/README.namelist (ep_para_read, rden_bin, and use_4denvar)
commit 25c8d802fb7c0d7945aa34c6b56dc72ef290ec24
Author: smileMchen <chenming@ucar.edu>
Date: Fri Oct 21 11:04:33 2016 -0600
FLG radiation scheme 320 -> 345 K fix (#21)
Type: Bug fix
Keywords: FLG radiation scheme
. . .
This process can also be used to correct a wide variety of other mistakes in your commit! Whether you made an error in the commit message, forgot to add a file, accidentally included changes that shouldn't have been included, committed as the wrong user, etc.: all of these situations can be fixed with git commit --amend
. And you can amend a commit as many times as you want, so long as you don't make a new, different commit after the old one you want to correct.
List all the git "variables", including information about where your repository came from (origin), who created the clone, what your default editor is, etc.
> git var -l
core.trustctime=false
credential.helper=osxkeychain
user.name=Michael Kavulich
user.email=kavulich@ucar.edu
push.default=simple
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
remote.origin.url=https://github.com/wrf-model/WRF
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
branch.AER-radiation.remote=origin
branch.AER-radiation.merge=refs/heads/AER-radiation
GIT_COMMITTER_IDENT=Michael Kavulich <kavulich@ucar.edu> 1476414213 -0600
GIT_AUTHOR_IDENT=Michael Kavulich <kavulich@ucar.edu> 1476414213 -0600
GIT_EDITOR=vim
GIT_PAGER=less
Shows the log message and the text diff for a given commit.
>git show e005cab
commit e005cab00e829f842def74b9f8812b63809e3a02
Author: kkeene44 <kkeene@ucar.edu>
Date: Fri Sep 23 14:16:39 2016 -0600
Fixed restart problem for tmn_update option
TYPE: bug fix - posted
KEYWORDS: tmn_update, restart, Registry, Registry.EM_COMMON, regional climate
SOURCE: Heimo Truhetz of University of Graz, Austria
DESCRIPTION OF CHANGES:
Added a "r" in the registry line for TLAG to add variable to restart files. Since TLAG was left out of the restart file, any restart using the tmn_update option started with 0 K as the lower boundary condition for the land model. When running long simulations (i.e, regional climate runs), this caused the soil temperature to cool gradually, eventually affecting the skin and atmospheric temperature. This change corrects the problem.
This has been an issue since Version 3.7.
LIST OF MODIFIED FILES : Registry/Registry.EM_COMMON
TESTS CONDUCTED : Tests conducted to ensure problem is corrected. Regression test passed.
diff --git a/Registry/Registry.EM_COMMON b/Registry/Registry.EM_COMMON
index 1ecc596..710627c 100644
--- a/Registry/Registry.EM_COMMON
+++ b/Registry/Registry.EM_COMMON
@@ -1674,7 +1674,7 @@ state real TMN ij misc 1 - i012rhd=(int
state real TYR ij misc 1 - rd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TYR" "ANNUAL MEAN SFC TEMPERATURE" "K"
state real TYRA ij misc 1 - rd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TYRA" "ACCUMULATED YEARLY SFC TEMPERATURE FOR CURRENT YEAR" "K"
state real TDLY ij misc 1 - rd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TDLY" "ACCUMULATED DAILY SFC TEMPERATURE FOR CURRENT DAY" "K"
-state real TLAG i&j misc 1 - d=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TLAG" "DAILY MEAN SFC TEMPERATURE OF PRIOR DAYS" "K"
+state real TLAG i&j misc 1 - rd=(interp_mask_field:lu_index,iswater)u=(copy_fcnm) "TLAG" "DAILY MEAN SFC TEMPERATURE OF PRIOR DAYS" "K"
state integer NYEAR - misc 1 - r "NYEAR" "ACCUM DAYS IN A YEAR" ""
state real NDAY - misc 1 - r "NDAY" "ACCUM TIMESTEPS IN A DAY" ""
state real XLAND ij misc 1 - i02rhd=(interp_fcnm_imask)u=(copy_fcnm) "XLAND" "LAND MASK (1 FOR LAND, 2 FOR WATER)" ""
git diff --name-status [hash/branch] [hash/branch]
Shows the SVN-style list of changed files between two hashes and/or branches.
-
If given no arguments, it will return a list of changed files that have NOT been staged for commit
-
If given two arguments, it will show the difference between the first branch/hash given and the second. Note that the order is important: If you do this command with two arguments, it will always compare the second argument to the first argument. So if I have a branch "new_branch" where I added a file "new_file", the command to see the difference between that branch and the master should look like this:
> git diff --name-status master new_branch A README_NEW
If I do it backwards, it gives a (perhaps) unexpected result:
>git diff --name-status new_branch master
D README_NEW
This is because it always assumes that the second argument is the branch/hash that you're interested in. So compared to that other branch, README_NEW is "deleted" in the master.
-
If given one argument, it works exactly like above, and git assumes the second argument is your currently-checked-out code plus all staged changes. So in the above example, if I have staged a file named "README_2" with git add, but have not yet committed it, I will see this:
>git diff --name-status new_branch A README_2 D README_NEW