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

source

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>

source

Reverting a modified file

git checkout -- <file>

source

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) and git 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 or git 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 and git mv isn't necessary.

Rename of Move files in Git

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 variable clean.requireForce is not set to false, 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).

source

git