Git入门技巧

  1. Git入门技巧
    1. 初始化
    2. 入门
      1. 创建存储库
      2. 做出改变
      3. 配置
      4. 使用分支
      5. 临时提交
      6. 观察你的存储库
      7. 忽略文件 .gitignore
      8. 重构文件名
      9. 同步
      10. 远程
      11. 跟踪路径更改
      12. git 配置 ssh 代理
    3. 技巧
      1. 重命名分支
      2. Log
      3. 分支
      4. Commit
      5. 忽略文件的权限变化
      6. Git 别名
      7. 修改远程 Commit 记录
      8. 撤销远程记录
      9. 放弃本地修改内容
      10. 获取最近一次提交的 Hash
      11. 删除已经合并到 master 的分支
      12. 把 A 分支的某一个 commit,放到 B 分支上
      13. 回到远程仓库的状态
      14. 重设第一个 commit
      15. 查看冲突文件列表
      16. 展示工作区的冲突文件列表
      17. 展示暂存区和最近版本的不同
      18. 中文乱码的解决方案
      19. 展示暂存区、工作区和最近版本的不同
      20. 删除已经合并到 master 的分支
      21. 关联远程分支
      22. 查看远程分支和本地分支的对应关系
      23. 展示当前分支的最近的 tag
      24. 查看某段代码是谁写的
      25. 修改作者名
      26. 修改远程仓库的 url
      27. 增加远程仓库
      28. 列出所有远程仓库
      29. 查看两个星期内的改动
      30. 从 stash 中拿出某个文件的修改
      31. 展示所有 tracked 的文件
      32. 展示所有 untracked 的文件
      33. 展示所有忽略的文件
      34. 把某一个分支导出成一个文件
      35. 从包中导入分支
      36. 执行 rebase 之前自动 stash
      37. 从远程仓库根据 ID,拉下某一状态,到本地分支
      38. 详细展示一行中的修改
      39. 清除 gitignore 文件中记录的文件
      40. 展示忽略的文件
      41. commit 历史中显示 Branch1 有的但是 Branch2 没有 commit
      42. 在 commit log 中显示 GPG 签名
      43. 新建并切换到新分支上,同时这个分支没有任何 commit
      44. 展示任意分支某一文件的内容
      45. 配置 http 和 socks 代理
      46. clone 最新一次提交
      47. 忽略某个文件的改动
      48. 以最后提交的顺序列出所有 Git 分支
      49. 在 commit log 中查找相关内容
      50. 把暂存区的指定 file 放到工作区中
      51. 配置 SSH 协议代理
    4. 代码统计
      1. 查看 git 上的个人代码量
      2. 统计每个人增删行数
      3. 查看仓库提交者排名
      4. 提交数统计

Git入门技巧

大家在实际开发中肯定少不了接触Git,Git是常用的版本控制系统,我们熟知的大型同性交友网站Github就依赖Git.

Git是一个强大的工具,这里罗列一下它的一些工具,相信看完这篇文章你也可以熟练的使用Git的命令行。

这里就不讲解安装方法了,关于Git的安装详见 起步 - 安装 Git


初始化

在安装之后我们需要设置用户名和邮箱,Git通过这些信息判断提交代码的用户。

如果你安装Git只是为了拉取公共仓库,那通常不需要设置此项。

# 用户名
git config --global user.name 'xxx'

# 邮箱
git config --global user.email 'xxx@xxx.xxx'

入门

创建存储库

创建一个新的本地存储库

$ git init [项目名称]

克隆存储库(代码仓库)

$ git clone <git_url>

将存储库克隆到指定目录

$ git clone <git_url> 指定目录

将存储库克隆到指定目录,并指定分支

$ git clone <git_url> -b <分支名称> 指定目录

做出改变

在工作目录中显示修改后的文件,为您的下一次提交暂存

$ git status

暂存文件,准备提交

$ git add [file]

暂存所有更改的文件,准备提交

$ git add .

将所有暂存文件提交到版本化历史记录

$ git commit -m "commit message"

将所有跟踪的文件提交到版本化历史记录

$ git commit -am "commit message"

取消暂存文件,保留文件更改

$ git reset [file]

将所有内容恢复到最后一次提交

$ git reset --hard

已更改但未暂存内容的差异

$ git diff

已 commited 但尚未提交的内容的差异

$ git diff --staged

在指定分支之前应用当前分支的任何提交

$ git rebase [branch]

配置

设置将附加到您的提交和标签的名称

$ git config --global user.name "name"

设置将附加到您的提交和标签 tags 的电子邮件地址

$ git config --global user.email "email"

启用 Git 输出的一些着色

$ git config --global color.ui auto

在文本编辑器中编辑全局配置文件

$ git config --global --edit

显示本地 repo 配置设置

$ git config --list

删除全局设置

$ git config --global --unset <entry-name>

使用分支

列出所有本地分支

$ git branch

列出所有分支,本地和远程

$ git branch -av

切换到 my_branch,并更新工作目录

$ git checkout my_branch

创建一个名为 new_branch 的新分支

$ git checkout -b new_branch

删除名为 my_branch 的分支

$ git branch -d my_branch

将分支 A 合并到分支 B

$ git checkout branchB
$ git merge branchA

标记当前提交

$ git tag my_tag

从远程分支中创建并切换到本地分支

$ git checkout -b <branch-name> origin/<branch-name>

临时提交

# 保存已修改和分阶段的更改
$ git stash
# 列出隐藏文件更改的堆栈顺序
$ git stash list
# 从存储堆栈顶部编写工作
$ git stash pop
# 丢弃存储堆栈顶部的更改
$ git stash drop
# 回到某个 stash 的状态
$ git stash apply <stash@{n}>
# 删除所有的 stash
$ git stash clear

观察你的存储库

显示当前活动分支的提交历史

$ git log

显示 branchA 上不在 branchB 上的提交

$ git log branchB..branchA

显示更改文件的提交,即使跨重命名

$ git log --follow [file]

显示 branchA 中的内容与 branchB 中的内容的差异

$ git diff branchB...branchA

以人类可读的格式显示 Git 中的任何对象

$ git show [SHA]

忽略文件 .gitignore

文件 .gitignore 指定了 Git 应该忽略的 未跟踪的 文件,在实际使用中可以避免提交缓存和已经生成的文件。

符号 作用
行首 # 全行注释,不支持行尾类注释*(转义 \#)*
行首**!** 否定模式*(转义 \!)*
** 匹配任意路径
* 匹配任意多个字符
? 匹配任意一个字符
doc/** 匹配 doc文件夹下的全部内容
doc/**/a 匹配任意深度路径下的 a文件或文件夹
/ 表示路径分隔符,不区分操作系统
/结尾 仅会匹配文件夹,否则会匹配文件和文件夹
空行 不匹配任何文件
行尾空格 默认被忽略,可使用 \进行转义
行首空格 被正常处理,不会被忽略

当前 .gitignore 文件定义规则的优先级高于上级路径 .gitignore 定义规则的优先级;后定义的规则优先级高于前面定义规则的优先级

# 忽略当前目录logs文件夹下的全部内容
/logs/
/logs/*
/logs/**
# 上述几条规则等效

# 忽略 Mac 系统文件,包括任意子路径下的同名文件(夹)
.DS_store

# 忽略 node_modules 文件夹,包括任意子路径下的同名文件夹
node_modules/

# 忽略任意子路径下build、target文件夹,
# 但不忽略src/main、src/test下的build、target文件夹
build/
!**/src/main/**/build/
!**/src/test/**/build/
target/
!**/src/main/**/target/
!**/src/test/**/target/

# 使用 ! 重新包含指定文件(夹)
!logs/.gitkeep

重构文件名

# 从工作目录中删除文件并暂存删除
git rm <filename>

# 从版本控制中删除文件但在本地保留文件
git rm --cached <filename>

# 更改文件名并准备提交
git mv <filename-orig> <filename-renamed>

同步

从该 Git 远程获取所有分支

$ git fetch [alias]

将远程分支合并到当前分支以使其保持最新状态

$ git merge [alias]/[branch]
# 没有快进
$ git merge --no-ff [alias]/[branch]
# 仅快进
$ git merge --ff-only [alias]/[branch]

将本地分支提交传输到远程存储库分支

$ git push [alias] [branch]

从跟踪远程分支获取并合并任何提交

$ git pull

将另一个分支的一个特定提交合并到当前分支

$ git cherry-pick [commit_id]

远程

添加一个 git URL 作为别名

$ git remote add [alias] [url]

显示您设置的远程存储库的名称

$ git remote

显示远程存储库的名称和 URL

$ git remote -v

删除远程存储库

$ git remote rm [remote repo name]

更改 git repo 的 URL

$ git remote set-url origin [git_url]

跟踪路径更改

从项目中删除文件并暂存删除以进行提交

$ git rm [file]

更改现有文件路径并暂存移动

$ git mv [existing-path] [new-path]

显示所有提交日志,并指示任何移动的路径

$ git log --stat -M

git 配置 ssh 代理

$ cat ~/.ssh/config
Host gitlab.com
# 直接使用 sh**socks 提供的 socks5 代理端口
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p 

Host github.com
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p  

技巧

重命名分支

  • 重命名new
$ git branch -m <new>
$ git branch -m <old> <new> #重命名分支  
  • 推送并重置
$ git push origin -u <new>
  • 删除远程分支
$ git push origin --delete <old> #方法1
$ git push origin :oldBranchName #方法2

Log

按内容搜索更改

$ git log -S'<a term in the source>'

显示特定文件随时间的变化

$ git log -p <file_name>

打印出很酷的日志可视化

$ git log --pretty=oneline --graph --decorate --all

分支

列出所有分支及其上游

$ git branch -vv 

快速切换到上一个分支

$ git checkout -

只获取所有远程分支

$ git branch -r

从另一个分支签出单个文件

$ git checkout <branch> -- <file>

删除本地存在远程不存在的分支

git remote prune origin

Commit

$ git commit -v --amend

重写最后的提交信息

忽略文件的权限变化

git config core.fileMode false

不再将文件的权限变化视作改动

Git 别名

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

也可以看看:更多别名### 设置大小写敏感

# 查看git 的设置
$ git config --get core.ignorecase
# 设置大小写敏感
$ git config core.ignorecase false
# 远程有俩相同目录,通过这种方式清除掉,然后提交记录
$ git rm -r --cached <目录/文件> 

修改远程 Commit 记录

$ git rebase -i HEAD~3
# 表示要修改当前版本的倒数第三次状态
# 将要更改的记录行首单词 pick 改为 edit
pick 96dc3f9 提交 commit 描述内容 1
pick f1cce8a 提交 commit 描述内容 2
pick 6293516 提交 commit 描述内容 3
# Rebase eeb03a4..6293516 onto eeb03a4 
#                     (3 commands)
#
# Commands:
# p, pick = 使用提交
# r, reword = 使用提交,但编辑提交消息
# e, edit = 使用提交,但停止修改
# s, squash = 使用提交,但融合到先前的提交中
# f, fixup = 像 squash,但丢弃此提交的日志消息
# x, exec = 使用 shell 运行命令(该行的其余部分)
# d, drop = 删除提交

保存并退出,会弹出下面提示

# 您现在可以修改提交,使用
# 
#   git commit --amend
# 
# 对更改感到满意后,运行
# 
#   git rebase --continue
#
# 1. 通过这条命令进入编辑更改 commit,保存退出
$ git commit --amend
# 2. 保存退出确认修改,继续执行下面命令, 
$ git rebase --continue
# 如果修改多条记录反复执行上面两条命令直到完成所有修改

# 最后,确保没有人提交进行推送,最好不要加 -f 强制推送
$ git push -f origin master

撤销远程记录

# 撤销一条记录   
$ git reset --hard HEAD~1
# 强制同步到远程仓库  
$ git push -f origin HEAD:master

放弃本地修改内容

# 如果有的修改以及加入暂存区的话
$ git reset --hard 
# 还原所有修改,不会删除新增的文件
$ git checkout . 
# 下面命令会删除新增的文件
$ git clean -xdf

获取最近一次提交的 Hash

$ git rev-parse HEAD # e10721cb8859b2c
# 获取短 hash
$ git rev-parse --short HEAD # e10721c

删除已经合并到 master 的分支

$ git branch --merged master | grep -v '^\*\|  master' | xargs -n 1 git branch -d

把 A 分支的某一个 commit,放到 B 分支上

# 切换到 B 分支
$ git checkout <B>
# 将 A 分支 <hash-id> 的内容 pick 到 B 分支
$ git cherry-pick <hash-id>

回到远程仓库的状态

$ git fetch --all && git reset --hard origin/master

抛弃本地所有的修改,回到远程仓库的状态

重设第一个 commit

$ git update-ref -d HEAD

把所有的改动都重新放回工作区,并 清空所有的 commit ,这样就可以重新提交第一个 commit

查看冲突文件列表

$ git diff --name-only --diff-filter=U

展示工作区的冲突文件列表

输出工作区和暂存区的 different (不同)。

$ git diff

还可以展示本地仓库中任意两个 commit 之间的文件变动:

$ git diff <commit-id> <commit-id>

展示暂存区和最近版本的不同

git diff --cached

中文乱码的解决方案

$ git config --global core.quotepath false

展示暂存区、工作区和最近版本的不同

$ git diff HEAD

输出工作区、暂存区 和本地最近的版本(commit)的different(不同)。

删除已经合并到 master 的分支

$ git branch --merged master | grep -v '^\*\|  master' | xargs -n 1 git branch -d

关联远程分支

$ git branch -u origin/mybranch

或者在 push 时加上 -u 参数

git push origin/mybranch -u

关联之后,git branch -vv 就可以展示关联的远程分支名了, 同时推送到远程仓库直接:git push,不需要指定远程仓库

查看远程分支和本地分支的对应关系

$ git remote show origin

展示当前分支的最近的 tag

$ git describe --tags --abbrev=0

查看某段代码是谁写的

$ git blame <file-name>

blame 的意思为 责怪,你懂的。

修改作者名

$ git commit --amend --author='Author Name <email@address.com>'

修改远程仓库的 url

$ git remote set-url origin <URL>

增加远程仓库

$ git remote add origin <remote-url>

列出所有远程仓库

$ git remote -v

查看两个星期内的改动

$ git whatchanged --since='2 weeks ago'

从 stash 中拿出某个文件的修改

$ git checkout <stash@{n}> -- <file-path>

展示所有 tracked 的文件

$ git ls-files -t

展示所有 untracked 的文件

$ git ls-files --others

展示所有忽略的文件

$ git ls-files --others -i --exclude-standard

把某一个分支导出成一个文件

$ git bundle create <file> <branch-name>

从包中导入分支

$ git clone repo.bundle <repo-dir> -b <branch-name>

新建一个分支,分支内容就是上面 git bundle create 命令导出的内容

执行 rebase 之前自动 stash

$ git rebase --autostash

从远程仓库根据 ID,拉下某一状态,到本地分支

$ git fetch origin pull/<id>/head:<branch-name>

详细展示一行中的修改

$ git diff --word-diff

清除 gitignore 文件中记录的文件

$ git clean -X -f

展示忽略的文件

$ git status --ignored

commit 历史中显示 Branch1 有的但是 Branch2 没有 commit

$ git log Branch1 ^Branch2

在 commit log 中显示 GPG 签名

$ git log --show-signature

新建并切换到新分支上,同时这个分支没有任何 commit

$ git checkout --orphan <branch-name>

相当于保存修改,但是重写 commit 历史

展示任意分支某一文件的内容

$ git show <branch-name>:<file-name>

配置 http 和 socks 代理

# 查看代理
$ git config --global http.proxy
$ git config --global https.proxy
$ git config --global socks.proxy

# 设置代理
# 适用于 privoxy 将 socks 协议转为 http 协议的 http 端口
$ git config --global http.proxy http://127.0.0.1:1080
$ git config --global https.proxy http://127.0.0.1:1080
$ git config --global socks.proxy 127.0.0.1:1080

# 取消代理
$ git config --global --unset http.proxy
$ git config --global --unset https.proxy
$ git config --global --unset socks.proxy

# 只对 github.com 设置代理
$ git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
$ git config --global https.https://github.com.proxy socks5://127.0.0.1:1080

# 取消 github.com 代理
$ git config --global --unset http.https://github.com.proxy
$ git config --global --unset https.https://github.com.proxy

clone 最新一次提交

$ git clone --depth=1 https://github.com/user/repo.git

只会 clone 最近一次提交,将减少 clone 时间

忽略某个文件的改动

关闭 track 指定文件的改动,也就是 Git 将不会在记录这个文件的改动

git update-index --assume-unchanged path/to/file

恢复 track 指定文件的改动

git update-index --no-assume-unchanged path/to/file

以最后提交的顺序列出所有 Git 分支

git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads

最新的放在最上面

在 commit log 中查找相关内容

git log --all --grep='<given-text>'

通过 grep 查找,given-text: 所需要查找的字段

把暂存区的指定 file 放到工作区中

git reset <file-name>

不添加参数,默认是 -mixed

配置 SSH 协议代理

# 对于使用 git@ 协议的,可以配置 socks5 代理
# macOS 系统编辑 ~/.ssh/config 文件,添加这几行,设置 github 代理
Host github.com
  ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p

代码统计

查看 git 上的个人代码量

  • username 需要改成自己的
git log --author="username" --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 10

提交数统计

git log --oneline | wc -l

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3400639399@qq.com

×

喜欢就点赞,疼爱就打赏

github