0%

常用git命令

前言

学习工作中,越来越习惯使用git,本文记录一下常用的git命令,方便以后查阅。

配置

用户名配置

1、全局配置

1
2
3
git config --global --list
git config --global user.name "voidking"
git config --global user.email "voidking@qq.com"

2、针对单独项目配置

1
2
3
git config --list
git config user.name "haojin"
git config user.email "voidking@vip.qq.com"

提交的时候,如果项目自身没有配置信息就会使用全局配置,有配置就会使用单独的配置信息。

免密上传下载

方法一:
1、生成ssh密钥
ssh-keygen -t rsa -C "voidking@qq.com",按3个回车,密码为空。

C:\Users\Administrator\.ssh下,得到两个文件id_rsa和id_rsa.pub。
需要注意的是,命令中的-C参数,后面跟的内容是注释。也就是说,内容随意,与github完全无关。

2、在GitHub上添加SSH密钥
打开id_rsa.pub,复制全文。访问github的 settings-ssh 页面,New SSH key,粘贴进去。

3、测试
ssh git@github.com,提示:

1
2
3
4
5
6
The authenticity of host 'github.com (192.30.252.128)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.252.128' (RSA) to the list of known hosts.
Hi voidking! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

方法二:
1、生成access token
访问github的 Personal access tokens 页面,Generate new token。
Note输入 voidking-pc ,Select scope选择repo,然后点击Generate token。生成了一个token,保存它。

2、开启密码记录
git config --global credential.helper store
用户家目录下的 .gitconfig 文件末尾会添加:

1
2
[credential]
helper = store

3、记住密码
再次使用git pull或者git push,系统会提示输入git用户名和密码,这里的密码输入access token即可,不要使用真实密码。
系统会记住用户的access token,存储在用户家目录下的 .git-credentials 文件中。之后就不再需要输入git密码了。

修改commit的用户名和邮箱

参考Changing author info,以macos上操作为例。

1、clone项目

1
2
git clone --bare https://github.com/user/repo.git
cd repo.git

2、创建修改用户名的脚本 change-author.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

其中 OLD_EMAIL、CORRECT_NAME、CORRECT_EMAIL 三个变量需要替换。

3、执行脚本
sh change-author.sh

4、检查结果,强制同步到远程仓库

1
2
git log
git push --force --tags origin 'refs/heads/*'

下载项目

克隆项目

1
2
3
4
5
6
7
8
# 普通克隆
git clone https://github.com/voidking/voidking.git

# 克隆并重命名为vk
git clone https://github.com/voidking/voidking.git vk

# 使用access token克隆项目
git clone https://<gh_token>@github.com/voidking/voidking.git

PS:下载失败问题解决 SSL certificate problem

1
git config --global http.sslVerify false

开启代理

如果克隆项目特别慢,自己又有科学上网的ssr,那么可以开启代理。

1
2
git config --global http.proxy 'socks5://127.0.0.1:1080' 
git config --global https.proxy 'socks5://127.0.0.1:1080'

关闭代理:

1
2
git config --global --unset http.proxy
git config --global --unset https.proxy

拉取项目

.git/config文件里,配置了remote和branch,以下为例。

1
2
3
4
5
6
7
8
9
10
11
12
13
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
[remote "origin"]
url = https://github.com/voidking/voidking.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master

拉取项目的时候,会根据这个配置来拉取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 查看本地分支追踪的远程分支
# 一个本地分支可以追踪多个远程分支
git branch -vv

# 格式说明
git pull <远程仓库名> <远程分支名>:<本地分支名>

# 拉取当前分支追踪的唯一远程分支
git pull

# 拉取当前分支追踪的origin/master分支
git pull origin master
git pull origin

# 拉取remote origin的next分支,与本地master合并
git pull origin next:master

# 拉取origin主机的next分支,与当前分支合并
git pull origin next

切换分支

1、查看分支

1
git branch -a

2、切换分支和新建分支

1
2
3
4
5
6
7
8
# 切换远程分支
git checkout origin/branch_name

# 新建与当前分支相同的分支
git checkout -b new_branch

# 新建与远程分支相同的分支
git checkout -b new_branch origin/branch_name

上传项目

上传分支

1
2
3
4
5
6
7
8
9
10
11
12
# 提交代码
git add .
git commit -m "something"

# 格式说明
git push <远程仓库名> <本地分支名>:<远程分支名>

# 上传代码到唯一远程追踪分支
git push

# 上传到指定远程追踪分支
git push origin HEAD:branch_name

修改commit message

git commit -m "something",之后,想要修改“something”为“something_new”。

使用git commit --amend,可以修改最后一次commit的附加信息。

查看日志

使用git log,只可以查看到当前分支的commit日志,而且不能查看已经删除了的commit操作。

若要查看全局日志,需要使用git reflog或者git log -g,可以查看所有分支的所有操作记录,包括reset操作、checkout操作、已经删除了的commit操作等等。

版本回退

版本回退常用git resetgit revert命令,这两个命令都是作用于当前分支(HEAD所在的分支)。git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。

reset

1、每个文件单独版本回退

1
2
3
4
git status
git log
git reset 1fe37e1bcbb894a1b594cf405ae31880cbaa6cd7 filepath/filename
git checkout filepath/filename

2、全部文件版本回退

1
git reset --hard 1fe37e1bcbb894a1b594cf405ae31880cbaa6cd7

3、远程仓库回退

1
2
git reset --hard 1fe37e1bcbb894a1b594cf405ae31880cbaa6cd7
git push -f

4、回退后回退
reset后,回退版本之后的commit操作记录,都被删除掉了。
如果回退过之后又后悔了,那么,需要查看全局日志,然后再次执行reset操作。

1
2
git reflog
git reset a246dcd --hard

需要注意的是,版本回退,我们没有使用git checkout
假设当前在bugFix分支,使用git checkout,理论上输入如下命令:

1
2
git reflog
git checkout a246dcd

这时,输入git log,发现版本完美回退了。但是,这只是假象,输入git branch -a,发现HEAD从bugFix分支切换到了a246dcd那个commit。而bugFix分支,没有进行任何改变。所以,我们不使用git checkout进行版本回退,而是使用它进行历史版本的查看。

revert

1、全部文件版本回退

1
git revert cf000

2、远程仓库回退

1
git push origin HEAD:branch_name

回退过之后又后悔了,那么,执行reset操作即可。

1
2
git log
git reset a246dcd --hard

git push 403

公司电脑(win10系统)以前有一个用户,github账号是haojin。现在电脑分配给我使用,但是,我的github账号是voidking,在我git push的时候报错403。

1
2
3
$ git push
remote: Permission to voidking/hexo-back-up.git denied to haojin.
fatal: unable to access 'https://github.com/voidking/hexo-back-up.git/': The requested URL returned error: 403

哪怕重置了全局设置的user.name和user.email,依然会报错。
原因:win10系统自动保存用户凭据,gitpush的时候默认使用以前的用户凭据。
解决办法:Win+X,搜索,控制面板,用户账户,凭据管理器,管理Windows凭据,普通凭据,删除github的凭据即可。

git stash

本地有修改, 但是想更新服务器上代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 保存stash
git stash
git stash save "something"

# 拉取最新代码
git pull

# 查看stash
git stash list

# 弹出之前的修改
git stash pop

# 弹出之前的修改(只能恢复一次)
git stash pop stash@{num}

# 弹出之前的修改(可恢复多次)
git stash apply stash@{num}

# 删除stash
git stash drop stash@{num}

# 删除所有stash
git stash clear

统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 统计个人代码量
git log --author="voidking" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

# 统计每个人代码量
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done

# 统计提交者前五
git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5

# 统计提交者数量
git log --pretty='%aN' | sort -u | wc -l

# 统计提交数
git log --oneline | wc -l

# 添加或修改的代码行数
git log --stat|perl -ne 'END { print $c } $c += $1 if /(\d+) insertions/'