Git commands
Posted on Sun 16 August 2020 in git
This post contains git commands that I often employ. At the end of the post, you will also find some things that I am not sure if were properly done (but they worked).
Using git diff
Scenario You use git add filename
and now you want to see the differences of the file before and after adding it to the staged files:
~/git/moea_mls/experiments/test_mls_v3 $ vim test.py # make some changes
~/git/moea_mls/experiments/test_mls_v3 $ git diff test.py # add to the staged files
You can use git diff --cached
to show the differences of the file:
~/git/moea_mls/experiments/test_mls_v3 $ git diff --cached
It will display something like this:
diff --git a/experiments/test_mls_v3/test.py b/experiments/test_mls_v3/test.py
index 22f5fb9..8e95285 100644
--- a/experiments/test_mls_v3/test.py
+++ b/experiments/test_mls_v3/test.py
@@ -1,5 +1,5 @@
# test.py
-# %run test.py -a mls_v2 -p dtlz1 -m 3 -f te --weights_type regular
+# %run test.py -a mls_v3 -p dtlz1 -m 3 -f te --weights_type regular
When
git diff
is invoked with the--cached
option the diff will compare the staged changes with the local repository. The--cached
option is synonymous with--staged
. Comparing changes with git diff
Scenario You want to see the differences of a file in two revisions. You can compare two branches with each other as follows:
$ git diff master..testing
or two revisions:
$ git diff 729d8df..a60c292
or a specific file in two revisions:
$ git diff 729d8df..a60c292 test.py # test.py is in the current working directory
Undo git add
git reset <file>
Reverting a modified file
git checkout -- <file>
Show files in a commit
Preferred way
git diff-tree --pretty -r bd61ad98 # specific commit
git diff-tree --no-commit-id --name-only -r bd61ad98 # specific commit
git diff-tree --no-commit-id --name-only HEAD # last commit
Alternative way (it may change over time)
git show --pretty="" --name-only bd61ad98
Relevant comment
If anyone is wondering (like I was) why the first way is "preferred," it goes back to @drizzt 's comment;
git show
is "porcelain" (meant to be user facing) andgit diff-tree
is "plumbing" (meant to be used programmatically, e.g. from scripts). The interface for the former may change over time (so the git maintainers could drop--name-only
although I don't imagine they would) for useability reasons, whereas the interface for the latter will be kept as stable as possible for compatibility reasons. – killscreen
Source: How to list all the files in a commit?
Appendix
Renaming files
I discovered this by accident. Suppose you remove a file with git rm file_a.txt
and immediately, add another file with git add file_b.txt
. Git will interpret this as renaming file_a.txt
as file_b.txt
:
[dev] auraham@rocket ~/Desktop/repo $ git init
Initialized empty Git repository in /home/auraham/Desktop/repo/.git/
Big Bang [dev] auraham@rocket ~/Desktop/repo $ touch file_a.txt
Big Bang 1? [dev] auraham@rocket ~/Desktop/repo $ git add file_a.txt
Big Bang 1✔ [dev] auraham@rocket ~/Desktop/repo $ git commit file_a.txt -m "Add file_a.txt"
[master (root-commit) 46668b9] Add file_a.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file_a.txt
master [dev] auraham@rocket ~/Desktop/repo $ git rm file_a.txt
rm 'file_a.txt'
master 1✔ [dev] auraham@rocket ~/Desktop/repo $ touch file_b.txt
master 1✔ 1? [dev] auraham@rocket ~/Desktop/repo $ git add file_b.txt
master 1✔ [dev] auraham@rocket ~/Desktop/repo $ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: file_a.txt -> file_b.txt
Then, I found that this is a handy trick of git, but it will only work if both files share a few lines in common:
In Git's case, it will try to auto-detect renames or moves on
git add
orgit commit
; if a file is deleted and a new file is created, and those files have a majority of lines in common, Git will automatically detect that the file was moved andgit mv
isn't necessary.
The recommended approach for renaming a file in git is with git mv file new_file_name
, for instance:
$ git mv dog.py puppy.py
$ git commit -m "Rename dog.py -> puppy.py"
This is the full log:
master 1? [dev] auraham@rocket ~/Desktop/repo $ git add dog.py
master 1✔ [dev] auraham@rocket ~/Desktop/repo $ git commit dog.py -m "Add dog.py"
[master a9308f6] Add dog.py
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dog.py
master [dev] auraham@rocket ~/Desktop/repo $ git mv dog.py puppy.py
master 1✔ [dev] auraham@rocket ~/Desktop/repo $ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: dog.py -> puppy.py
master 1✔ [dev] auraham@rocket ~/Desktop/repo $ git commit -m "Rename dog.py -> puppy.py"
[master 039cf9a] Rename dog.py -> puppy.py
1 file changed, 0 insertions(+), 0 deletions(-)
rename dog.py => puppy.py (100%)
Unfinished pull
I made a git pull
, but it was interrupted since there was no more space left in the disk. After removing old files, I tried git pull
again, but it cannot be done:
git pull
[list of files from the unfinished git pull, now marked as untracked files]
Please move or remove them before you can merge.
Aborting
Thus, before performing git pull
, we need to remove the files from the unfinished git pull
. To this end, we can use git clean
to remove untracked files from the working tree.
Note Before going any further, be sure that your local copy is older than the remote copy (i.e., gitlab). In my case, my local copy is two revisions behind the remote copy:
# local copy
git log --oneline
d736e6c ...
# remote copy
34b5ef84 ...
e0ea64d5 ...
d736e6c1 ...
Use this command to show the files to
git clean -n -d
where:
-d
remove untracked directories in addition to untracked files.-n
don't actually remove anything, just show what would be done.
To actually remove the untracked files, you can use one of these options:
-i
(--interactive
) show what would be done and clean files interactively-f
(--force
) if the Git configuration variableclean.requireForce
is not set tofalse
,git
clean will refuse to delete files or directories unless given-f
,-n
or-i
. Git will refuse to delete directories with.git
sub directory or file unless a second-f
is given.
I recommend to use:
git clean -d -i
This command will show a prompt with more options to remove the files (such as using a pattern).