常用 Git 指令攻略

工作里习惯了经过 Fork(app)运用 Git,这两个月的时刻里开始了解 Git 的指令行客户端。虽然指令行在视觉上不如 UI 直观,但指令行能够坚持双手持续输入不离开键盘,了解指令行也更利于寻找最合适自己的 GUI。

别的,界面的直观指的是个人运用上的直观。界面有琳琅满目的信息,鼠标有五湖四海的方向,当某个人不了解界面的时分,我只能当面告知他怎样履行这些 git 指令:“点这里,这里,这里,往上一点,点顶部菜单栏左边第二个按钮”,这不如指令行直观。

下面的内容包含了 Git 常用的指令,以及各指令或详或简但有必要的解说阐明,其中也包含了很多相关的引用链接用于扩展阅览。

推送和拉取

推送:

# 推送长途,并设置当时分支的 upstream 为 main,设置之后每次推送当时分支只需求 git push 即可
git push -u origin main
# 推送长途至 upstream,假如没有设置,在 git 2.0 之前,一切同名分支被推送,git 2.0 之后,报错
git push
# 强制推送
git push -f
# 推送至长途,可是设置长途分支称号
git push origin hehe:haha

拉取:

git checkout -b <local-branch> origin/<remote-branch> # 拉取长途指定分支并检出

git push的默许行为:默许行为根据 git 装备里的push.default的值决定,在 git 2.0 之前的默许值是matching,之后的是simple,所以在 2.0 之后假如没有设置上游分支 upstream 就会报错。

push.default的可选值:

  • nothing,禁止git push,必须显式指定推送分支,比如git push origin master
  • current,把本地分支推送至长途,长途分支名和本地分支名相同;
  • upstream,推送到 upstream 上;
  • tracking,同上一个upstream,不引荐运用;
  • simple,推送到 upstream 上,可是要保证 upstream 的分支名和本地分支名相同;
  • matching,推送一切的本地和长途相同称号的分支。

设置local(库房)等级的默许推送行为:

git config push.default nothing

相关链接:

  • Git push与pull的默许行为:解说了什么是upstreamdownstream
  • push.default:社区文档的解说;
  • What is the difference between ‘git pull’ and ‘git fetch’?:git pullgit fetch的差异,git pull = git fetch + git merge FETCH_HEAD

分支

检查分支:

# 检查一切分支
git branch -a
# 检查本地分支
git branch
# 检查长途分支
git branch -r

删去分支:

# 删去本地分支(删去不了未兼并过的分支)
git branch -d feature-album
# 删去未兼并过的本地分支
git branch -D feature-album # 大写的 D
# 删去长途分支
git push origin --delete feature-album # 榜首种办法
git push origin :refs/branch/feature-album # 第二种办法,这种办法适用在,分支名和标签名相一同,履行榜首种办法会抵触报错,则运用这个办法,由于榜首种办法也能够用来删去标签

检出长途分支:

git checkout -b <local-branch> origin/<remote-branch> # 拉取长途指定分支并检出

重命名分支(本地):

# 重命名当时分支
git branch -m <new_name> # -m 是 --move 短格局
# 重命名指定分支
git branch -m <old_name> <new_name>
# 在大小写无感的文件系统中重命名分支
git branch -M <New_Name> # 假如不是用 -M,会报错 fatal: 一个分支名 'new_name' 已经存在

克隆

git clone git@github.com:wswmsword/git-learning.git

克隆一切分支,并切换到指定分支:

git clone -b main git@github.com:wswmsword/git-learning.git # 克隆一切分支,并切换到 main

克隆指定分支:

git clone -b main --single-branch git@github.com:wswmsword/git-learning.git # 克隆 main

克隆指定文件夹(git 2.25+ (Q1 2020)):

mkdir git-sparse-checkout && cd git-sparse-checkout # 创立并进入文件夹
git init -q # 静默初始化
git remote add origin git@github.com:wswmsword/git-learning.git
git sparse-checkout set assets # 设置指定文件夹,文件夹路径为 assets
git pull origin main
ls # assets
git sparse-checkout disable # 关闭 sparse-checkout

旧版别的 git 克隆指定文件夹:

mkdir git-sparse-checkout-old && cd git-sparse-checkout-old
git init -q
git remote add origin git@github.com:wswmsword/git-learning.git
git config --global core.sparseCheckout true
echo "assets" >> .git/info/sparse-checkout
git pull origin main

相关链接:

  • How to disable sparse checkout after enabled?:翻开稀少检出后怎样关闭?答复中有运用老版别的 git 关闭答案。答复中说到了一个脚本。
  • sparse_checkout.sh:榜首条中说到的脚本。
  • sparse-checkout:git 的稀少检出社区文档。

提交

暂存:

git add . # 暂存一切改动文件
git add -e <filename> # 把一个文件里的部分行移至暂存,暂存一部分
git add -p <filename> # 交互式,履行后将输出选项供挑选,挑选 e 能够暂存一部分
git add -u # 除未盯梢的文件外,把一切文件暂存
git add --ignore-removal . # 除已删去的文件外,暂存一切的文件

提交:

# 提交,增加信息
git commit -m "junior commit"
# 提交指定文件(这里的文件是 file-abc)
git commit file-abc -m "add single file"
# 提交,翻开默许修正器修正提交信息
git commit
# 暂存已盯梢的文件,一同提交(省掉了 git add 指令,可是这里只能暂存已盯梢文件)
git commit -am "junior commit"
# 提交,翻开默许修正器修正提交信息,包含 diff 信息
git commit -v
# 提交,允许空提交信息
git commit --allow-empty-message
# 修正上一次提交
git commit --amend -m "better message was committed"
# 翻开默许修正器,修正前次提交信息
git commit --amend
# 修正前次提交的邮箱
git commit --amend --author "New Authorname <authoremail@mydomain.com>"

检出某一条提交记载:

git checkout <commit-hash>

git add -Agit add .git add -u的差异(Git 2.x):

指令(Git 2.x) 新文件 修正的文件 删去的文件 描绘
git add -A 暂存一切(新的、修正的、删去的)文件
git add . 暂存一切(新的、修正的、删去的)文件
git add -u 暂存修正的和删去的文件,不暂存未盯梢的新文件
git add –ignore-removal . 暂存新文件和修正的文件,不暂存删去的文件

在 Git 2.0 之前的版别,git add .不能暂存已删去的文件。

相关链接:

  • Git 2.0, git add -A is default:git 源码里的文档,说到了git add <path>在 Git 2.0 版别之后,履行的作用和git add -A <path>相同;
  • What’s the difference between git add . and git add -u?。
  • git add .与git add -A的差异(版别不一同分的差异):1.x 和 2.x 版别之间 add 指令的差异。

兼并

# 指定分支兼并到当时分支
git merge feature-album
# 安全兼并
git merge --no-ff --no-commit my-branch # --no-commit 不主动提交,--no-ff 不运用 fast-forward(快进)
# 兼并的时分把一个分支兼并成一条记载
git merge --squash feature-album
# 兼并分支不提交记载
git merge feature-album --no-commit
# 中止兼并(处理抵触的阶段)
git merge --abort

兼并其它分支的一个文件:

git checkout --patch testing-merge-file features/album/audio-formats # 兼并 testing-merge-file 分支的 features/album/audio-formats 文件

履行完上面的指令后进入优选项的交互界面,挑选 e(manually edit the current hunk),进行文件的抵触修正,最终保存,文件会在暂存区内。

假如指令中不加--patch,履行完指令的行为是当时分支的文件被指定分支的文件掩盖:

git checkout testing-merge-file features/album/audio-formats # 当时分支的文件 features/album/audio-formats 被 testing-merge-file 分支的掩盖

关于git merge <branch>fast-forward情况下和git rebase <branch>的差异:

方针分支超越主分支,而且主分支没有新的提交记载,

            *E-*F-*G-*H-*I    BRANCH
           /
*A-*B-*C-*D                   MAIN

fast-forwardgit rebase兼并的作用相同,

*A-*B-*C-*D-*E-*F-*G-*H-*I MAIN | BRANCH

,当主分支有了新的提交(J、K),

            *E-*F-*G-*H-*I    BRANCH
           /
*A-*B-*C-*D-*J-*K             MAIN

,就无法运用fast-forward,兼并之后必须有一个独自的兼并节点,可是git rebase依然能够兼并,而且能坚持提交线的整齐,

*A-*B-*C-*D-*J-*K-*E'-*F'-*G'-*H'-*I'             MAIN | BRANCH

,有抵触的节点由于处理抵触会生成新的commit-id,有相同提交的记载会被方针分支的节点掩盖,rebase的节点也纷歧定是接连的,可能会穿插到主分支已经提交的节点中(按提交先后)。

关于三方兼并:

            master
             |
*C0-*C1-*C2-*C4
          \
           *C3-*C5
                |
               iss53

在这样的分支结构中,要把iss53兼并到master,要运用C4C5和公共先人C2,这三个节点做一个三方兼并。

三方兼并有利于主动兼并:例如,节点 C2 有文件 F 包含内容

一
二

,节点 C4 的文件 F 包含内容

,节点 C5 的文件 F 包含内容

一
二
三

,现在把iss53兼并至master,由于三方兼并,文件 F 的内容变成了


二
三

,由于 C4 在 C2 的根底上清空了榜首行,C5 在 C2 的根底上添补了第三行,C2、C4、C5 都有第二行,所以兼并的结果是清空榜首行、保存第二行和添补第三行,这其中需求公共先人 C2 的参与。

提示:当兼并处理完抵触后,修正提交信息,“增加一些细节给未来检视这个兼并的读者一些协助,告知他们你是怎样处理兼并抵触的,以及理由是什么”。

相关链接:

  • 兼并 (版别操控):维基的兼并解说,包含三方兼并;
  • 怎样了解Git里的 “three-way merge” ? – Lazykid的答复 – 知乎:三方兼并解说;
  • How to merge specific files from Git branches:stackoverflow 的引荐答复;
  • 3.2 Git 分支 – 分支的新建与兼并:社区文档;
  • Git Merge Fast-Forward vs Git Rebase:StackOverflow 上关于fast-forwardrebase差异的答案。

变基 rebase

首先要提一下 rebase 的意思,我擅自的直譯是「从头 (re-) 定義某個 branch 的參考基準 (base)」。把這個意思先記起來,比較容易了解 rebase 的運作原理。就比如偷梁换柱那樣(稼接),把某個樹枝接到別的樹枝。——Git-rebase 小筆記

运用变基兼并几条提交记载:

git rebase -i <commit_id_start> <commit_id_end> # 前开后闭

下面是运用变基兼并 5 条记载的例子:

兼并22bafc6以上的记载至4f4a863共 5 条,履行上面的指令后(这里是git rebase -i 22bafc6 4f4a863),默许修正器将翻开相似下面的文件:

pick 478a9ab add album/history
pick 63e6dd5 add album/length
pick 0d72816 add album/tracks
pick d49335e add album/audio-formats
pick 4f4a863 add album/types
# 变基 22bafc6..4f4a863 到 22bafc6(5 个提交)
#
# 指令:
# p, pick <提交> = 运用提交
# r, reword <提交> = 运用提交,但修正提交阐明
# e, edit <提交> = 运用提交,但中止以便在 shell 中修补提交
# s, squash <提交> = 运用提交,但挤压到前一个提交
# f, fixup [-C | -c] <提交> = 相似于 "squash",但只保存前一个提交
#                    的提交阐明,除非运用了 -C 参数,此情况下则只
#                    保存本提交阐明。运用 -c 和 -C 相似,但会翻开
#                    修正器修正提交阐明
# x, exec <指令> = 运用 shell 运转指令(此行剩下部分)
# b, break = 在此处中止(运用 'git rebase --continue' 持续变基)
# d, drop <提交> = 删去提交
# l, label <label> = 为当时 HEAD 打上符号
# t, reset <label> = 重置 HEAD 到该符号
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       创立一个兼并提交,并运用原始的兼并提交阐明(假如没有指定
# .       原始提交,运用注释部分的 oneline 作为提交阐明)。运用
# .       -c <提交> 能够修正提交阐明。
#
# 能够对这些行从头排序,将从上至下履行。
#
# 假如您在这里删去一行,对应的提交将会丢掉。
#
# 但是,假如您删去全部内容,变基操作将会中止。
#

修正,将前 2-5 行的pick改为s(s 代表上面注释里的 squash),表明这 4 条记载将兼并到榜首条记载中,最终保存:

pick 478a9ab add album/history
s 63e6dd5 add album/length
s 0d72816 add album/tracks
s d49335e add album/audio-formats
s 4f4a863 add album/types
# ...省掉

然后,默许修正器会进入第二个文件,用于修正兼并这 5 条记载的提交信息。

进行修正,在榜首行增加提交信息(add album features),最终保存:

add album features
# 这是一个 5 个提交的组合。
# 这是榜首个提交阐明:
add album/history
# 这是提交阐明 #2:
add album/length
# 这是提交阐明 #3:
add album/tracks
# 这是提交阐明 #4:
add album/audio-formats
# 这是提交阐明 #5:
add album/types
# ...省掉

完成上面的过程之后,就生成了一条记载,这条记载包含了原分支从22bafc64f4a863的 5 条记载,git 的HEAD(头指针)会指向这条提交记载上。可是现在,这条记载不属于任何分支,所以一旦切换分支,这条记载就会丢掉。

假如要把这条记载合回原分支:

git checkout -b rebased-album-features # 从 HEAD 检出分支
git checkout feature-album # 检出原分支(feature-album)
git reset --hard 22bafc6 # 回滚到五条兼并指令前(留意:操作将清空工作区和暂存区)
git rebase rebased-album-features

常用 Git 命令指南


变基替代兼并:

git rebase feature-album # 分支 feature-album 变基到当时分支

相关链接:

  • “git 小白求助,怎样高雅的回滚过去某次过错的 merge,并保存 merge 之后 commit 的改动”;
  • Git-rebase 小筆記。

文件的四种状况

UntrackedStagedUnmodifiedModified

  • Untracked(未盯梢)
    • 榜首次新建的文件,没有git add过的文件,或许git rm --cached过的文件;
  • Staged(暂存)
    • git add过的文件都是staged状况;
  • Unmodified(未修正)
    • git commit后的文件是未修正状况;
  • Modified(已修正)
    • git commit之后,对文件进行修正,当时为已修正状况。

也有文档解说中多出第五种状况—:“已提交(committed)”,已提交相当于Unmodified未修正状况。

日志

简洁日志,包含短 id 和提交信息:“git log --oneline”。

图形形式的提交记载,包含短 id,提交信息,相对时刻,作者称号:

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
# 这一段指令很长,为了便利,后边介绍了用别号替代这条指令的办法
# --abbrev-commit 的意思是,展现缩写的 commit_id,abbreviation

常用 Git 命令指南

用关键字过滤日志:

git log --all --grep="microsoft" # 查询包含“microsoft”的提交记载
git log --all --oneline --grep="microsoft" # 查询包含“microsoft”的提交记载,查询结果只包含 8 位 hash 和提交信息

运用reflog检查操作历史(reflog是本地的,无法经过git pull得到):

git reflog
# 检查某一个文件的提交记载
git log -p <file> # -p 检查具体的 diff
# 展现一切的提交记载,例如在某个分支需求检查最新的提交信息时,能够运用这条指令
git log --oneline --all # 参数 --all 表明展现一切提交记载
# 检查指定分支的提交记载
git log --oneline <branch_name> # 这条指令会展现包含兼并分支的一切细节提交记载,能够用选项 --first-parent 来只展现兼并节点,便利阅览
# 检查指定分支的提交记载(兼并分支的提交记载只挑选展现最终的兼并节点)
git log --oneline --first-parent <branch_name>

git log其它装备的指令:

git log -p [<file-name> | <commit>]# 显现差异
git log -g # 检查一切提交记载,包含 amend 的
git log --stat # 显现文件更改列表
git log --pretty=oneline # 一行显现提交信息
git log --pretty=short
git log --pretty=medium
git log --pretty=full
git log --pretty=fuller
git log --pretty=reference
git log --pretty=email
git log --pretty=raw
git reflog # 更多的记载
git log --oneline # 一行显现,更紧凑,哈希更短
git log --graph
git log --graph --oneline # 紧凑,短 commit-id
git log --pretty="%C(yellow) Hash: %h %C(blue)Date: %ad %C(red) Message: %s " --date=human
git log --pretty="%C(yellow) Hash: %h %C(blue)Date: %ad %C(red) Message: %s " --date=short
git log --relative-date # 相对时刻
git shortlog # 按作者,只展现注释日志
git log --author=wswmsword # 只看某人(wswmsword)的提交
git log --pretty=format:'%h %ad %an %s' --date=local # hash、日期、作者、信息,短格局的日期

format 的参数:

  • %h:commit hash
  • %ai: author date
  • %an: author name
  • %ci: commit date
  • %cn: commit name
  • %s: log message

前面说到的图形形式的提交记载指令很长,假如常用,为它设置别号会更便利:

git config --global alias.gg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

,这样设置后再履行指令git gg就相当于履行了git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

相关链接:

  • Pretty Git branch graphs。

疏忽文件

有两种疏忽文件或文件夹的办法,一,修正项目内的.git/info/exclude文件,在文件里增加需求疏忽的文件或文件夹,二,在项目里增加.gitignore文件,在文件里增加需求疏忽的文件或文件夹。

榜首种修正.git/info/exclude的办法合适疏忽偏个人的、不普遍的文件。例如,假如项目中每位开发者的开发东西不同,而有的开发东西会生成各自的装备文件,这样的装备文件可能不合适放在.gitignore中,不然多一个不同的开发东西就会多一条疏忽记载。

第二种创立.gitignore文件的办法合适疏忽通用的文件。例如*.log之类的日志文件。.gitignore能够被创立在不同的文件夹里,一同也会被当作项目的一部分,被 Git 盯梢管理。

创立.gitignore文件,在其中加入要疏忽的文件或文件夹。

.DS_Store

相关链接:

  • Git常用指令整理八(疏忽文件);
  • “When would you use .git/info/exclude instead of .gitignore to exclude files?”。

比较差异

# 比照暂存区差异
git diff --staged
# 比照工作区差异
git diff
# 和上一次提交比照
git diff HEAD~

diff 东西

  • 下载 diff 前端,这里是 Meld(其它 diff 东西:Beyond Compare、Araxis Merge、DiffMerge)
  • 增加装备,修正~/.gitconfig
[diff]
  tool = meld
[difftool]
  prompt = false
[difftool "meld"]
  trustExitCode = true
  cmd = open -W -a Meld --args \"$LOCAL\" \"$PWD/$REMOTE\"
[merge]
  tool = meld
[mergetool]
  prompt = false
[mergetool "meld"]
  trustExitCode = true
  cmd = open -W -a Meld --args --auto-merge \"$PWD/$LOCAL\" \"$PWD/$BASE\" \"$PWD/$REMOTE\" --output=\"$PWD/$MERGED\"

这样设置后,履行git difftool翻开 diff 东西进行文件比较。

补丁

生成一个补丁文件,自己或许共享其他人运用,举例:

git diff HEAD~ HEAD > patch-abc # 前次提交和倒数第2次提交的变更,生成补丁

这是生成的补丁文件,称号patch-abc

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5ca0973
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.DS_Store
+
git checkout HEAD~ # 把头移动到倒数第2次提交
git apply --check patch-abc # 检查能不能增加补丁
git apply patch-abc # 增加补丁,假如不能增加会提示失败

标签

标签分为“附注标签”和“轻量标签”,附注标签包含很多信息,例如标签的作者、邮箱、日期时刻等,而轻量标签只是简略的引用,是指向标签地点 commit 的指针。

# 检查本地标签
git tag
# 检查长途标签
git ls-remote --tags origin
# 特定模式(通配符)查找标签
git tag -l "chill-v*"
# 打标签(附注标签,包含标签作者、邮箱等信息,annotated tag)
git tag -a chill-tag -m "truly hot" # 假如增加标签信息,只要 -m 参数的时分,不加 -a,生成的标签同样是附注标签
# 打标签(轻量标签,commit 的指针,lightweight tag)
git tag hot-day # 当时 commit 生成名为 hot-day 的标签
# 给之前的 commit 打标签
git tag -a old-tag "all those years ago" <commit_id>
# 推送一切本地标签
git push origin --tags
# 推送指定标签
git push origin more-tag # 推送名为 more-tag 的标签
# 删去本地标签
git tag -d more-tag
# 删去长途标签
git push origin --delete more-tag # 榜首种办法
git push origin :refs/tags/more-tag # 第二种办法,这种办法适用在,分支名和标签名相一同,履行榜首种办法会抵触报错,则运用这个办法
# 检出标签
git checkout hot-day
# 检查标签的详细信息
git show hot-day
# 找到删去的标签地点的 commit
git fsck --unreachable | grep tag

点击检查开源项目 React 创立的一切标签。

储藏

# 检查储藏列表
git stash list
# 增加储藏,增加信息
git stash push -m "stash then go the other branch to fix bug" # 不增加信息,直接履行 git stash push
# 删去储藏
git stash drop stash@{0} # 删去储藏 stash@{0},stash@{0} 代表储藏的编号,一切储藏编号运用 git stash list 检查,假如不指定 stash@{0} 将删去最近的储藏
# 运用储藏
git stash apply stash@{0} # 不指定 stash@{0},即直接履行 git stash apply 将运用最顶部(最近增加的)储藏
# 推出储藏(运用并删去最顶部储藏)
git stash pop
# 增加储藏(包含未盯梢文件)
git stash -u # -u 即 --include-untracked,`git stash` == `git stash push`,假如要增加信息,增加 -m
# 交互式增加储藏(看到 diff,给选项进行挑选是否增加储藏)
git stash --patch
# 切新分支并运用储藏
git stash branch <branch-name>
# 检查储藏内容
git stash show -p # -p 显现详细信息
# 铲除未盯梢文件(交互式 -i)
git clean -d -i
# ?
git stash apply --index # ?

旧版别的git stash save从 Git2.16.0 起被弃用,点击检查。

相关链接:“What’s the difference between git stash save and git stash push?”。

遴选

# 遴选一条记载
git cherry-pick <commit-hash>
# 遴选多条记载(不接连)
git cherry-pick <commit-hash-a> <commit-hash-b>
# 遴选接连的多条记载(前开后闭)
git cherry-pick <commit-hash-a>...<commit-hash-c>
# 增加装备项 -n,遴选不产生提交记载,只更新工作去与暂存区
git cherry-pick -n <commit-hash>

什么是遴选:在下面的分支图里,假如 MAIN 分支需求 BRANCH 分支的节点H的改动,能够经过遴选把节点H增加到节点E的后边。

            *F-*G-*H-*I          BRANCH
           /
*A-*B-*C-*D-*E                   MAIN

从 BRANCH 分支遴选节点H至主分支:

            *F-*G-*H-*I          BRANCH
           /
*A-*B-*C-*D-*E-*H'               MAIN

相关链接:

  • git cherry-pick 教程。

回滚、吊销、重置

git reset

git reset HEAD@{1} # HEAD@{1} 指的是履行`git reflog`后看到的记载 id,HEAD@{1} 是倒数第二条,HEAD@{0} 是倒数榜首条,以此类推
git reset --soft <commit-hash> # 回退至 commit-hash 处,commit-hash 和当时的差异被放在暂存区
git reset # 一切暂存区的文件回到工作区
git reset --keep <commit-hash> # ?
git reset --merge <commit-hash> # ?

git revert

git revert <commit-id> # 回转并提交
git revert -n <commit-id> # 回转,不提交,需求持续履行 git revert --continue,或许中止回转,git revert --abort
git revert -n <commit-id-start>..<commit-id-end> # 前开后闭,回转几个(一段)提交
git revert HEAD@{1} # 回转最近提交

吊销某个文件至指定 commit 时的状况:

git checkout <commit-hash> -- <path/to/file>

关于git reset中的softmixedhard

  • --soft:当时(还没reset)工作区和暂存区的改动不变,还在原位,reset之后有了差异,差异在暂存区中;
  • --mixed:默许类型,reset前后一切改动都移到工作区中,包含原来在暂存区的,也移到工作区中;
  • --hard:清空工作区和暂存区的改动,直接将 HEAD 指向reset的指向,运用时要留意。

关于工作区、暂存区、History:工作区修正,add至暂存区,commit至 History。

一些名词:

  • 工作区:Working directory,Working Copy;
  • 暂存区:Index,索引,Staging area,Stage/Index;
  • History:HEAD 指的地方,提交记载的地方,Repository。

相关链接:

  • What’s the difference between git reset –mixed, –soft, and –hard?
  • 常用 Git 指令清单-九、吊销

责怪

git blame <file_name> # 检查文件每一行的修正记载,包含作者、日期和内容
git blame -L 6,9 <file_name> # 指定行数规模检查文件的修正记载
git blame -enl -L 6,9 <file_name> # 组合查询,包含邮箱,行数,完好哈希

相似 VSCode 上安装插件 GitLens 之后的作用,鼠标点击某一行后,会在那一行后边出现最近一次该行的提交信息,有时分会把这个信息当成代码注释。

GitLens 第 26 行的git blame -L 26,26 .internal/baseUniq.js的作用:

常用 Git 命令指南

装备

检查装备:

git config --global --list # 检查装备表
git config --global --get user.name # 检查用户名(global 等级)
git config --global --get user.email # 检查用户邮箱(global 等级)

修正用户名和邮箱:

git config user.name "wswmsword" # 设置用户名(local 等级)
git config user.email "cjzjzzz@gmail.com" # 设置邮箱(local 等级)

装备文件的等级:systemgloballocal

装备默许修正器:

# 常用修正器:emacs / nano / vim / vi
git config --global core.editor emacs

修正装备文件:

git config -e # 等价 vim .git/config
# 可加 --global,--system

设置文件大小写敏感:

git config --global core.ignorecase false # git 默许疏忽大小写

别号

设置指令的别号:

git config --global alias.haha  "status -sb" # 相当于 git status -sb
git config --global alias.ci  "commit" # 相当于 git commit

删去指令的别号:删去.git/config里对应别号地点行,假如是大局的别号,删去~/.gitconfig里对应别号地点行,或许:

git config --global --unset alias.haha # unset

自定义简略 log msg:

git config --global --replace-all alias.lg "log --pretty=format:'%h %ad %an %s' --date=local"

子模块

git submodule add https://github.com/wswmsword/git-submodule lyrics # 增加一个子模块,路径是 ./lyrics
git pull --recurse-submodules # 递归子模块拉取
git config submodule.recurse true
git submodule update --init # git pull 后拉取子模块内容
git submodule add ./submarines # 本地库房增加子模块
git submodule init
git submodule update
git submodule update --remote # 更新子模块至长途最新的提交记载
git submodule foreach "<git command>" # 对每个子模块履行 git 指令
git clone --recursive https://github.com/wswmsword/git-learning # 克隆项目,递归克隆子项目

删去子模块:

# step 1
git rm submarines # 删去文件夹 submarines(submarines 是子模块库房)
# step 2
rm -rf .git/modules/submarines
# step 3
vim .git/config # 删去 config 文件里的 submodule 装备,形如下面这一段
# [submodule "submarines"]
#     active = true
#     url = https://github.com/xxxxxxx.git

相关链接:

  • How to git submodule tutorial—— YouTube 视频;
  • Git子模块—— CSDN 文章,说到了子模块更新父模块为更新的情况;
  • 7.11 Git 东西 – 子模块—— Git 社区文档。

二分查找

运用git bisect指令,用二分法找到榜首条犯错的提交记载。

git bisect start <节点> <先人节点>
# 例如,git bisect start HEAD 4d83cfc
# 假如代码没有过错,就进行符号 good,git 接下来会向子孙持续查找
git bisect good
# 假如代码出现了过错,就进行符号 bad,git 接下来会向先人持续查找
git bisect bad
# 退出查找
git bisect reset

在最终一步符号后,git 会提示我们“<commit_id> is the first bad commit”。

相关链接:

  • Bisectercise——Github 库房,克隆下来用于练习“git bisect”;
  • git bisect 指令教程;
  • git-bisect——社区文档。

GUI

  • magit:Emacs git 客户端
  • fork:Mac git 客户端,简洁,便利,反应快
  • lazygit:指令行 git 客户端

修正文件称号的大小写

git mv SONG song2
git mv song2 song
git add .
git commit -m "rename 'song'"

两个相同称号的文件夹:

假如经过git config --global core.ignorecase false把文件名设置为大小写敏感后,修正本地文件夹songSong,然后上传,长途库房将存在两个称号相同、大小写不同的(song 和 Song)文件夹(git version 2.34.1, macOS 12.5 (21G72))。

相关链接:

  • 被文件名大小写的问题搞晕了:V2EX 上关于 Git 文件名大小写修正的讨论。

其它

git show,显现最近提交的信息,与之相关的其它指令:

git show <commit>
git show --raw <commit> # 检查提交文件列表
git show <commit> <file> # 检查提交记载的某文件 diff
git show HEAD^ # 前次提交
git show HEAD@{n} # 倒数第 n 次提交
git show <commit>:<file> # 检查一次提交的一个文件的改变
git show <branch> # 检查一个分支最近的一次提交
git show <branch>@{n} # 一个分支的倒数第 n 次提交

git restore --staged <file>吊销暂存。

Github 新创立库房的 Git 拉取提示:

echo "# git-learning" >> README.md # 创立一个文件,往里面加入文本
git init # 初始化 git
git add README.md
git commit -m "first commit"
git branch -M main # 重命名默许分支称号
git remote add origin git@github.com:wswmsword/git-learning.git
git push -u origin main

获取提交的数量:

git rev-list --count HEAD
git rev-list --count HEAD --since="Dec 3 2015"  --before="Jan 3 2016" # 一段时刻
git shortlog -s
git shortlog -s --all # -all 一切分支

切换上一次的分支:

git checkout - # 只需增加一个短杠,其它指令兴许也能用

检查文件的 SHA1 值:

git ls-files --stage # 检查一切文件的 SHA1 值
git hash-data <file-name> # 检查单文件的 SHA1 值

git rm

git rm <file>,吊销盯梢,而且删去指定文件。假如加上-r参数(git rm -r <file>),则删去文件夹。

git rm --cached <file>,吊销盯梢,保存工作区的文件内容。git rm -f <file>,强制删去文件。

不是一切的文件都需求 git 盯梢,例如项目编译之后的产包。假如产包由于误操作导致被盯梢了,就运用git rm指令来吊销盯梢,并把产包增加到.gitignore来疏忽盯梢。已盯梢的文件再增加到.gitignore中不会生效。

相关链接:

  • git疏忽已经被提交的文件——segmentfault 的答案,除了运用git rm --cached还供给了其它办法吊销盯梢已盯梢的文件。

git remote

git remote -v # 显现一切长途库房
git remote show origin # 显现某个长途库房的信息
git remote add <name> <url> # 增加长途版别库
git remote rm <name> # 删去长途库房
git remote rename <old_name> <name> # 修正库房名

引用

材料:

  • Git 飞行攻略
  • Git Book
  • Git 谈天入门
  • Pro Git
  • Git常用指令参考手册
  • 廖雪峰 git 教程
  • 跟我一同学 Git
  • Git 权威攻略
  • Oh Shit, Git!?!
  • Git常用指令整理
  • Awesome Git
  • 图解Git
  • git-tips

其它链接:

  • Git 试验库房 – git-learning——我创立的用于履行本学习记载里每一条指令的 git 库房;
  • Setting up and using Meld as your git difftool and mergetool on a Mac;
  • git-fire——在紧急情况下保存代码。