Git wiki - quick command reference
Here are the list of commands we use quite often.
remote means remote repository uri,
for example, https://github.com/User/myrepo.git
- To clone a remote git repository with depth = 1 and specifying my project name:
$ git clone --depth=1 remote myproject
- To clone a remote git repository with specific branch (eg. master):
$ git clone -b master remote
- To see the branches after cloned all branches (cloned w/o specifying any):
$ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/dev remotes/origin/master
- Switching branches (checkout -b):
$ git checkout -b dev Switched to a new branch 'dev'
- To setup local repo with a remote repositories.
First, we need to use git init and then use git remote add remote-name remote-url:$ git init
This will create .git directory into our current working directory. Now we want to add the remote repo:$ git remote add origin https://github.com/User/repo.git
Here the 4th one (origin), we can name it whatever we want to. But origin is a kind of convention. - To see what are the remote repositories:
$ git remote -v origin https://github.com/User/repo.git (fetch) origin https://github.com/User/repo.git (push)
If we want to use the same name, we can drop our project name which is the last argument. - To switch remote repositories from repo1 to repo2:
This is my current remote:$ git remote -v origin https://github.com/User/repo1.git (fetch) origin https://github.com/User/repo1.git (push)
Here it is:$ git remote set-url origin https://github.com/repo2.git
Note that we overwrote (replaced with a new remote) an existing one.
If we wanted to keep the old one, we could have used add instead of set-url:$ git remote add origin2 https://github.com/repo2.git
Then, we have two remote repos:$ git remote -v origin https://github.com/User/repo1.git (fetch) origin https://github.com/User/repo1.git (push) origin2 https://github.com/User/repo2.git (fetch) origin2 https://github.com/User/repo2.git (push)
There are couple of options when we do stage files.
- Staging only "modified (including deleted)":
$ git add -u
or$ git add --update
If we want to do commit at one shot:$ git commit -a
- Staging all (modified + new + deleted):
"git add -A" is equivalent to "git add --all"$ git add -A
or$ git add --all
As we can see from the table below, as far as Git 2, there is not difference "git add -A" and "git add ."
Just for demonstration purpose, I put my file (a.txt) in several stage with a text of that stage name:
- A file on working directory (working tree) - "My Working directory file"
- A file in staging area - "My Staged file"
- A file already committed - "My HEAD file"
- A file already pushed to remote - "My Remote file"
So, when we issue a diff command, we can see the diff more clearly.
- After we staged a file, and want to see the diff of the file from the one that's already in the HEAD (local repo):
$ git diff --staged a.txt -My HEAD file +My Staged file
- Worked on a file that's on our working directory (or working tree), and want to see the diff from the one already staged:
$ git diff a.txt -My Staged file +My Working directory file
- To see the diff of my file on working tree with the one already in the HEAD
$ git diff HEAD a.txt -My HEAD file +My Working directory file
- To see the diff of my file on working tree with the remote one.
To be more clear, we may want to know how the remote looks like:$ git remote -v origin https://github.com/User/repo.git (fetch) origin https://github.com/User/repo.git (push)
Now, let's do diff:
$ git diff origin/master:a.txt a.txt -My remote file +My Working directory file
We can switch the positions$ git diff HEAD:a.txt origin/master:a.txt -My HEAD file +My remote file
The command "checkout" is versatile.
- Reverting a commit: let's get a copy of committed file. Suppose we have the following git log:
$ git log --oneline f7ec51a line 12 added f28dbdb line 11 added 1ed1386 additional 5 lines added there were 2 line 6s d7ae3ef 5 lines added bdbc7b6 initial commit
If we want to commit it back with acfd26c, we may use "checkout" command:
$ git checkout f28dbdb -- chap1
Note that we used "-- filename" to indicated we're NOT dealing with branches. The command will give a copy not only to our working area but also to staging index. We can see there is no difference between the two areas:
$ git diff $
We do tagging after a commit:
$ git tag -a 1.1.0
Other than marking the version, tag can be used similar to 'reset'. In other words, we can move the HEAD back and forth by checking out a tag. As shown below, the HEAD is on version 1.1.0.
We'll move the HEAD to version 1.0.0:
$ git checkout 1.0.0
We can also check it by opening the file on our working directory as well. Now, we can modify the file on our working directory, staging, and re-commit it:
$ git add chap1 $ git commit -m "added line 12 - 15" [master ecdbb8b] added line 12 - 15 1 file changed, 3 insertions(+) $ git log --oneline ecdbb8b added line 12 - 15 f7ec51a line 12 added f28dbdb line 11 added 1ed1386 additional 5 lines added there were 2 line 6s d7ae3ef 5 lines added bdbc7b6 initial commit
Note that we did NOT REWRITE a history!
- Switching branches:
$ git branch dev * master $ git checkout dev Switched to branch 'dev' $ git branch * dev master
If we use "-b" with checkout, it will create a new branch and will move head to that branch:
$ git checkout -b feature Switched to a new branch 'feature' $ git branch dev * feature master
The "git reset"s are confusing topic even for seasoned git users. We have 3 types of resets.
It's helpful if we picture it from the top level (indexed - committed), then staged, and then working directory, in that order.
Let's assume we have committed v1/v2/v3.
All the 3 types of resets will move back the HEAD to the previous commit (V2).
Starting from soft reset to mixed, and then hard reset.
Soft resets undo the indexed (committed), and put it back to the state before the commit. In other words, the status will be back to staging. So, v3 still in the staging level.
The mixed resets undo down to the staging. So, v3 is in the working directory:
The hard resets undo all down to working directory, wiping all. So, v3 is not even in the working directory, gone:
The followings are specific examples for the resets. Please play with your own cases.
- Soft Reset : git reset --soft
Here is our sample:
fcbac4c Line C added c96e962 Line B added 8fbccf9 Line A added ecdbb8b added line 12 - 15 f7ec51a line 12 added f28dbdb line 11 added 1ed1386 additional 5 lines added there were 2 line 6s d7ae3ef 5 lines added bdbc7b6 initial commit
We want to the latest 3 commits into one commit. To do that, we need to move HEAD down to the 4th one which is "ecdbb8b". The soft reset does it and bring the commit to our staging index:
$ git reset --soft ecdbb8b $ git log --oneline ecdbb8b added line 12 - 15 f7ec51a line 12 added f28dbdb line 11 added 1ed1386 additional 5 lines added there were 2 line 6s d7ae3ef 5 lines added bdbc7b6 initial commit
We see it moved the HEAD, and git does not aware that there were the three commits ever exist.
We can make it sure by doing diff between staging index and repository:
$ git diff --staged diff --git a/chap1 b/chap1 index aee59f2..c8c9397 100644 --- a/chap1 +++ b/chap1 @@ -17,3 +17,7 @@ line 12 line 13 line 14 line 15 + +line A +line B +line C
Again, the repository does not have the lines A,B, and C.
Now, we can just commit the file in the staging index.
$ git commit -m "Added A,B,C lines at one shot" $ git log --oneline e3d2156 Added A,B,C lines at one shot ecdbb8b added line 12 - 15 f7ec51a line 12 added f28dbdb line 11 added 1ed1386 additional 5 lines added there were 2 line 6s d7ae3ef 5 lines added bdbc7b6 initial commit
We made one commit instead of committing 3 times for each line!
- Mixed Reset (default) : git reset
This reset makes our staging index the same as our repository by bring down the commited (HEAD) file to staging index. So, there will be difference between the staging index and our working directory:
$ git diff --staged $
Let's start from the previous log:
$ git log --oneline e3d2156 Added A,B,C lines at one shot ecdbb8b added line 12 - 15 f7ec51a line 12 added f28dbdb line 11 added 1ed1386 additional 5 lines added there were 2 line 6s d7ae3ef 5 lines added bdbc7b6 initial commit
In the soft reset, we just committed the file in the staging index, and the file has all three lines A, B, C. But what if we want to modify the lines. In other words, we want to switch the label A, B, C to AA, BB, CC.
Let's do mixed reset which is the default:
$ git reset ecdbb8b
Let's modify the file in our working directory and commit it.
$ git add chap1 $ git commit -m "A,B,C->AA,BB,CC" [master 58d0aec] A,B,C->AA,BB,CC 1 file changed, 4 insertions(+) $ git log --oneline 58d0aec A,B,C->AA,BB,CC ecdbb8b added line 12 - 15 f7ec51a line 12 added f28dbdb line 11 added 1ed1386 additional 5 lines added there were 2 line 6s d7ae3ef 5 lines added bdbc7b6 initial commit
- Hard Reset : git reset --hard
This is dangerous since hard reset will wipe out our working directory as well as staging index. We may need to use more often than we thought. So, it's a good practice to commit frequently so that we may not lose our files in our working directory by an accidental hard reset.
Let's start from the previous log. We found the the line AA, BB, CC have full of bugs, and we want to scrap it away and start all over from the commit "ecdbb8b".
$ git reset --hard ecdbb8b
After the reset, our staging index and working directory will be cleaned up. In other words, there will be no difference among the repo, staging, and working directory.
$ git diff $ git diff --staged $
In short, we can think of the three resets as in the steps shown in the following picture.
- soft reset: before commit
- (mixed) reset: before add
- hard reset: before edit
Picture from Learn Git 22: Post-Reset Debreif:
Git/GitHub Tutorial
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization