Tools - Version Control - Git

闷骚的程序员

Common commands

FunctionOrder
Add files/changes to staging areagit add filename
Add all files/changes to staging areagit add .
Submitgit commit -m msg
Pull the latest code from the remote repositorygit pull origin master
Push to remote repositorygit push origin master
View configuration informationgit config –list
View file listgit ls-files
Comparing workspace and staging areagit diff
Comparing staging area and repositorygit diff –cached
Comparing workspaces and repositoriesgit diff HEAD
Remove files from staging areagit reset HEAD filename
View local remote warehouse configurationgit remote -v
Rollbackgit reset –hard submit SHA
Force push to remote repositorygit push -f origin master
Modified last commitgit commit –amend
Push tags to the remote repositorygit push –tags
Push a single tag to the remote repositorygit push origin [tagname]
Delete remote branchgit push origin –delete [branchName]
Remote empty branch (equivalent to delete)git push origin :[branchName]
View all branch historygitk –all
Display history sorted by dategitk –date-order

Q&A

How to solve the problem of Chinese garbled characters in gitk and Chinese file names in git ls-files?

Add the following to ~/.gitconfig

[core]
   quotepath = false
[gui]
   encoding = utf-8
[i18n]
   commitencoding = utf-8
[svn]
   pathnameencoding = utf-8

Reference http://zengrong.net/post/1249.htm

How to handle the situation where there are local changes that need to be merged in new code from the server?

git stash
git pull
git stash pop

stash

Check out the stash list:

git stash list

View the list of changed files of a certain stash (the latest one is displayed by default if the last parameter is not passed):

git stash show "stash@{0}"

Show changes as patches

git stash show -p "stash@{0}"

Apply a stash change:

git stash apply "stash@{0}"

How to merge upstream updates of a forked repository?

git remote add upstream https://upstream-repo-url
git fetch upstream
git merge upstream/master

How to handle the conflict generated by git through TortoiseMerge.exe with TortoiseSVN?

  • Add the path where TortoiseMerge.exe is located to the path environment variable.
  • Run the command git config --global merge.tool tortoisemerge to set TortoiseMerge.exe as the default merge tool.
  • Run git mergetool in the directory where the conflict is generated, TortoiseMerge.exe will pop up for you to resolve the conflict.

    You can also run git mergetool -t vimdiff to temporarily specify a merge tool to use with the -t parameter.

The files that you don’t want to track have been submitted, how to keep the local files without tracking them?

git rm --cached /path/to/file, then add and commit normally.

How not to create a branch without a parent?

git checkout --orphan newbranch

At this point, git branch will not show the branch until you make the first commit of the changes. For example, you may want to create an empty gh-pages branch, then:

git checkout --orphan gh-pages
git rm -rf .
// add your gh-pages branch files
git add .
git commit -m "init commit"

Common commands for submodules

Add submodule

git submodule add git@github.com:philsquared/Catch.git Catch

This will generate the following .gitmodules file in the repository root directory and clone the submodule locally.

[submodule "Catch"]
path = Catch
url = git@github.com:philsquared/Catch.git

Update submodule

git submodule update

When the remote of the submodule is updated, it is required

git submodule update --remote

When you pull the remote update of submodule locally, but want to go back:

git submodule update --init

Remove submodule

Delete the information of the corresponding submodule in .gitmodules, and then use the following command to delete all files of the submodule:

git rm --cached Catch

Pull submodule when cloning repository

git submodule update --init --recursive

delete remote tag

git push origin --delete tag [tagname]

Create a tag based on a commit

git tag <tag name> <commit id>
git tag v1.0.0 ef0120

Clear untracked files

git clean

Optional:

OptionsMeaning
-q, –quietDo not display deleted file names
-n, –dry-runTest run
-f, –forceForce
-i, –interactiveInteractive
-dDelete folder
-e, –excludeIgnore matches document

Ignore file attribute changes

A file was chmoded because of a temporary requirement, and as a result it was recorded as a change, which is sometimes desirable and sometimes annoying.

git config --global core.filemode false

Reference: How do I make Git ignore file mode (chmod) changes?

Ignore all files except a certain extension

All files except .c suffix are ignored.

*
!*.c
!*/

In gitignore, *, ?, [] can be used as wildcards.

###patch

Generate a patch file for changes not added to the staging area:

git diff > demo.patch

Generate a patch file with changes that have been added to the staging area:

git diff --cached > demo.patch

Merge the changes contained in the patch file generated by the two commands above:

git apply demo.patch

3 patch files will be generated from 3 commits before HEAD:

(HEAD can be replaced with sha1 code)

git format-patch -3 HEAD

Generate a patch file for commits between af8e2 and eaf8e:

(note that af8e2 is earlier than eaf8e)

git format-patch af8e2..eaf8e

Merge the patch files generated by the format-patch command:

git am 0001-Update.patch

Unlike git apply, this will add and commit directly.

only download latest code

git clone --depth 1 git://xxxxxx

The cloned repository will be in a shallow state, to make it a full version:

git fetch --unshallow

or

git pull --unshallow

Create a branch based on a commit

git checkout -b test 5234ab

Indicates to create a branch test based on the code with the commit hash of 5234ab.

Restore a single file to the specified version

git reset 5234ab MainActivity.java

Restore the MainActivity.java file to the state when the commit hash was 5234ab.

Set global hooks

git config --global core.hooksPath C:/Users/mazhuang/git-hooks

Then put the corresponding hooks file in the directory specified by the last parameter.

For example, if you want to set before commit, if it is detected that there is no synchronization from the server, commit is not allowed, then create a file pre-commit in the above directory, the content is as follows:

#!/bin/sh

CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

git fetch origin $CURRENT_BRANCH

HEAD=$(git rev-parse HEAD)
FETCH_HEAD=$(git rev-parse FETCH_HEAD)

if [ "$FETCH_HEAD" = "$HEAD" ];
then
    echo "Pre-commit check passed"
    exit 0
fi

echo "Error: you need to update from remote first"

exit 1

View the modification content of a commit

git show <commit-hash-id>

View the modification history of a file

git log -p <filename>

View the last two revisions

git log -p -2

Apply an existing change / merge a commit

git cherry-pick <commit-hash-id>

More detailed usage of cherry-pick can be found in the help documentation.

Command line autocompletion

Load the git-completion series of scripts in the shell, see https://github.com/git/git/tree/master/contrib/completion

Change details for each line of the file

git blame <filename>

Retrieve the past history

git reflog

Lists a list of commits that HEAD has pointed to, which only exist locally and are not part of the version repository.

and also:

git fsck

Remember username and password in http(s) mode

In some cases, the git protocol cannot be used. For example, the company’s git server has set up an IP whitelist and can only use ssh on the company’s intranet. Then, you can only use http(s) to upload and download source code outside, but manually every time. Entering the username/password is a pain in the ass, so just remember it.

Set remember password (default 15 minutes):

git config --global credential.helper cache

Customize the time to remember (eg one hour below):

git config credential.helper 'cache --timeout=3600'

Long-term storage of passwords:

git config --global credential.helper store

git commit Use vim to edit commit message Chinese garbled

This problem appeared under Windows, and I didn’t find a perfect solution. One way is to enter after vim is opened:

:set termencoding=GBK

This is a bit too cumbersome, and the compromise is to use gVim or other editor of your choice to edit the commit message instead:

git config --global core.editor gvim

refer to:

In addition, after upgrading Vim to 8.1, since the vim80 folder is still added to the PATH environment variable, it prompts when git commit:

error: cannot spawn gvim: No such file or directory
error: unable to start editor 'gvim'
Please supply the message using either -m or -F option.

Use which gvim to see:

$ which gvim
/usr/bin/which: no gvim in xxxxxxx

Change the vim80 path added in the PATH to vim81 and solve it.

git log Chinese garbled characters

Only encountered under Windows.

git config --global i18n.logoutputencoding gbk

Edit the etc/profile file in the git installation directory and add the following at the end:

export LESSCHARSET=utf-8

Reference: Git for windows Chinese garbled solution

git diff Chinese garbled characters

It is only encountered under Windows, and no effective solution has been found yet.

Count lines of code

Direct execution under CMD may fail, you can right-click and execute it in Git Bash here.

Count someone’s code commits

git log --author="$(git config --get user.name)" --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "added lines: %s removed lines : %s total lines: %s\n",add,subs,loc }'

Top 5 repository committers

To see all, just remove the head pipe.

git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5

Top 5 repository committers (emails)

This statistic may not be accurate and may have the same name.

git log --pretty=format:%ae | gawk -- '{ ++c[$0]; } END { for(cc in c) printf "%5d %s\n",c[cc],cc; } ' | sort -u -n -r | head -n 5

Contributor Ranking

git log --pretty='%aN' | sort -u | wc -l

Commits statistics

git log --oneline | wc -l

Reference: Git Code Line Statistics Command Set

Case problem when modifying file name

When modifying the case of the file name, it will be ignored by default (under Windows). The method to make git case-sensitive:

git config --global core.ignorecase false

Or using git mv oldname newname is also possible.

Fix gitk display blur issue on macOS

gitk is very convenient, but the default display under Mac system is very blurred, which affects the experience.

According to the results of online search, there are two solutions, I use the first solution, the second did not try.

method one:

  1. Restart the machine, press command + R, etc. Logo and progress bar appear, it will enter Recovery mode, select the utility tool at the top - terminal, and run the following command:

     csrutil disable
    
  2. Restart the machine.

  3. Edit the Wish program’s plist to enable high-resolution screen support.

     sudo gvim /System/Library/Frameworks/Tk.framework/Versions/Current/Resources/Wish.app/Contents/Info.plist
    

    Add the following code before the final </dict>

     <key>NSHighResolutionCapable</key>
     <true/>
    
  4. Update Wish.app.

     sudo touch Wish.app
    
  5. Use step 1 to enter Recovery mode again, execute csrutil enable to enable protection of system files, and then restart.

Reference: Resolving gitk ambiguity in Mac

Method Two:

brew cask install retinizer
open /System/Library/Frameworks/Tk.framework/Versions/Current/Resources/

Open the retinizer and drag Wish.app to the retinizer’s interface.

Reference: Deep Git-Git Foundation

Specify a branch other than master when clone

git clone -b <branch name> --single-branch <repo address>

Get current branch name

git symbolic-ref --short -q HEAD

Solve no man viewer handled the request

Running the command git stash --help reports an error:

warning: failed to exec man: Invalid argument
fatal: no man viewer handled the request

The reason is that there is no man command under Windows.

The git configuration can be modified so that the help documentation for the command is opened through the browser.

git config --global help.format web

Compare the diff of two branches

Show all difference details:

git diff <branch_name_1> <branch_name_2>

Display a list of files with differences:

git diff <branch_name_1> <branch_name_2> --stat

Display diff details for the specified file:

git diff <branch_name_1> <branch_name_2> <filename>

Check out the commits that branch A has and branch B does not:

git log <branch_name_A> ^<branch_name_B>

Alarm during git operation

Warning message:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The ECDSA host key for gitlab.xxxx.com has changed,
and the key for the corresponding IP address 121.40.151.8
is unknown. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:bud2tDwxl9687vMOUUBGXlwZhjxDTu7eVF43ojAu1Pw.
Please contact your system administrator.
Add correct host key in /c/Users/mzlogin/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /c/Users/mzlogin/.ssh/known_hosts:1
ECDSA host key for gitlab.xxxx.com has changed and you have requested strict checking.
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Solution:

rm ~/.ssh/known_hosts

Then do it again.

Delete the local branch that does not have a corresponding remote branch

(The validity of this section is questionable, and sometimes it does not work.)

$ git remote show origin
develop                             tracked
master                              tracked
feature/new-ui                      tracked
refs/remotes/origin/feature/test    stale (use 'git remote prune' to remove)
...

Where feature/test is a local branch that does not exist a remote branch.

$ git remote prune origin

Clearing is complete.

Information

Search

    Table of Contents