Git是一个非常强大的代码管理工具,它不仅可以让你方便地提交、推送、拉取代码,还可以让你灵活地处理各种复杂的分支、合并、冲突等问题。说到使用,相信大家都会,无非就是commit、push、pull 。但是如果要说熟练掌握Git的使用,对代码管理做到得心应手却不是那么容易。现在我们就先从基本的概念开始,系统地学习Git的原理和操作。
👉 概念篇
基本使用
创建新仓库
# 本地初始化git
git init
# 关联远程仓库
git remote add <shortname> <url>
检出/克隆仓库
# 克隆远程仓库,并且直接使用仓库名作为文件夹名称
git clone <仓库地址>
# 克隆,并且自定义本地文件夹名称
git clone <仓库地址> "文件名"
添加和提交
将文档添加到暂存区
# 添加指定文件
git add <filename>
# 或直接使用*号添加全部
git add *
将暂存区内容提交
# -m表示message
git commit -m "代码提交信息"
# -a表示all
git commit -am "代码提交信息"
-am是两个选项的组合,-a表示all,-m表示message。
- -a选项可以让git commit自动把已经跟踪过的文件(即修改或删除的文件)添加到暂存区,而不需要先用git add命令。
- -m选项可以让你直接在命令行中输入提交信息,而不需要打开文本编辑器。
例如,
git commit -am “修改了a.txt”
就会把修改过的a.txt
文件添加到暂存区,并且创建一个带有修改了a.txt
信息的提交。
推送代码
# 把 master 换成你想要推送的任何分支
git push origin master
# 指定分支
git push -u origin master
-u是一个选项,表示set-upstream,也就是设置上游分支。 使用-u选项可以让本地分支和远程分支建立关联,这样在以后的推送或拉取操作中就不需要指定分支名了。
如果你的本地分支和远程分支有关联(upstream),那么你可以直接用git push命令,不用再写远程仓库和分支的名字。 例如,如果你的本地分支foo关联了远程仓库origin的foo分支,那么你可以直接用
git push
来推送本地foo分支到远程foo分支,而不用写git push origin foo
。如果你的本地分支没有关联远程分支,那么你就需要指定分支名,或者使用-u选项来建立关联。 例如,如果你有一个新的本地分支bar,你想推送到远程仓库origin的bar分支,那么你可以用
git push origin bar
或者git push -u origin bar
来推送, 并且后者会让这两个分支关联起来。
分支处理
# 创建分支
git branch <分支名称>
# 切换分支
git checkout 分支名称
# 命令合并(创建并切换到新的分支)
git checkout -b 分支名称
# 删除指定分支
git branch -d 分支名称
# 强制删除指定分支(没有被合并到 mas -d 改成 -Dter 过的 branch 在删除时会失败,如果确认要删除这个分支,则可以可以把 -d 改成 -D,即把小写换成大写)
git branch -D 分支名称
# 使用该分支推送
git push origin <分支名称>
# 拉取远程分支
git fetch <remote>
# 查看分支列表
git branch
# 查看每一个分支的最后一次提交
git branch -v
# 查看哪些分支已经合并到当前分支
git branch --merged
# 查看所有包含未合并工作的分支
git branch --no-merged
更新合并
# 拉取远程代码
git pull
# 合并指定分支
git merge <branch>
# 预览分支差异
git diff <source_branch> <target_branch>
其他命令
# 查看所有分支
git branch -a
# 查看当前配置有哪些远程仓库及其地址
git remote -v
# 查看文件处于什么状态
git status
进阶用法
add
add
指令除了 git add 文件名
这种用法外,还可以使用 add .
来直接把工作目录下的所有改动全部放进暂存区
# 所有改动全部放进暂存区
git add .
# 查看暂存状态
git status
通过
add
添加进暂存区的不是文件名,而是具体的文件改动内容。
push
push
是把当前的分支上传到远程仓库,并把这个 branch
的路径上的所有 commit
也一并上传。
push
的时候,如果当前分支是一个本地创建的分支,需要指定远程仓库名和分支名,用 git push origin branch_name
的格式,而不能只用 git push
;或者可以通过 git config
修改 push.default
来改变 push
时的行为逻辑。
push
的时候之后上传当前分支,并不会上传 HEAD
;远程仓库的 HEAD
是永远指向默认分支(即 master
)的。
merge
merge
的意思是「合并」,它做的事也是合并:指定一个 commit
,把它合并到当前的 commit
来。具体来讲,merge
做的事是:
从目标
commit
和当前commit
(即HEAD
所指向的commit
)分叉的位置起,把目标commit
的路径上的所有commit
的内容一并应用到当前commit
,然后自动生成一个新的commit
。
示例:把branch1合并到master
HEAD
指向了 master
,所以如果这时执行:
git merge branch1
Git 会把 5
和 6
这两个 commit
的内容一并应用到 4
上,然后生成一个新的提交
适用场景
merge
最常用的场景有两处:
- 合并分支
当一个
branch
的开发已经完成,需要把内容合并回去时,用merge
来进行合并。
pull
的内部操作
pull
的实际操作其实是把远端仓库的内容用fetch
取下来之后,用merge
来合并。
冲突问题
当前分支和目标分支在使用merge
合并的时候,有一定的自动合并能力
1)修改不同的文件
如果一个分支改了 A 文件,另一个分支改了 B 文件,那么合并后就是既改 A 也改 B。这个动作会自动完成;
2)修改通一个文件,不同地方
如果两个分支都改了同一个文件,但一个改的是第 1 行,另一个改的是第 2 行,那么合并后就是第 1 行和第 2 行都改,也是自动完成。
3)修改同一个文件,同一个地方(冲突)
这种情况 Git 称之为:冲突(Conflict)。这个时候git不会自动合并,但是会把它们放在一起,由你来决定。
解决冲突
比如:
<<<<<<<< HEAD
文件1的内容
==========
文件2的内容
<<<<<<<<< dev
假设你决定保留 HEAD
的修改,那么只要删除掉 dev
分支的修改,再把 Git 添加的那三行 <<<
===
>>>
辅助文字也删掉,保存文件退出,「解决掉冲突」就完成了。
放弃解决冲突
当Git 仓库处于冲突待解决的中间状态,所以如果你最终决定放弃这次 merge
,则需要执行一次 merge --abort
来手动取消它:
# 输入这行代码, Git 仓库就会回到 merge 前的状态
git merge --abort
rebase
rebase
的意思是,给你的 commit
序列重新设置基础点(也就是父 commit
)。
展开来说就是,把你指定的 commit
以及它所在的 commit
串,以指定的目标 commit
为基础,依次重新提交一次。
有些人不喜欢
merge
,因为在merge
之后,commit
历史就会出现分叉,这种分叉再汇合的结构会让有些人觉得混乱而难以管理。如果你不希望commit
历史出现分叉,可以用rebase
来代替merge
。
和merge的区别
rebase
是在需要被 rebase
的 commit
上进行操作
使用rebase的一个常见场景是,当你在一个本地分支上开发新功能时,你想要把远程仓库中的最新更新合并到你的分支上,但是你又想保持你的分支历史简洁,好像你是在最新的基础上开发的一样。这样做的好处是,当你把你的分支合并回主分支时,可以避免一些不必要的合并冲突,也可以让你的提交历史更清晰,更容易追踪和调试。
示例
例如,假设你有一个名为dev
的本地分支,你在上面开发了一些新功能。同时,远程仓库中的主分支(origin/master
)也有了一些更新。你想要把这些更新合并到你的dev
分支上,但是你不想用merge命令,因为那样会产生一个多余的合并提交。你可以用rebase
命令来实现这个目的:
git checkout dev
git rebase origin/master
git checkout master
git merge dev
这样做会把你
dev
分支上相对于origin/master
分支的提交重新应用到origin/master
分支上,让你的dev
分支看起来像是从origin/master
分支最新的提交开始创建的。然后,当你想要把dev
分支合并回主分支时,只需要用git merge dev
命令就可以完成一个快进合并(fast-forward merge
),而不会产生任何冲突或多余的提交。
通过 rebase
,把ABC这条 commit
的基础点从 D 换成了 F。通过这样的方式,就让本来分叉了的提交历史重新回到了一条线。这种「重新设置基础点」的操作,就是 rebase
的含义。
为什么要切换到 dev
来 rebase
,然后再切回 master
再 merge
,而不是直接在 master
上执行 rebase
?
主要是为了避免和远端仓库发生冲突,rebase
后的 commit
虽然内容和 rebase
之前相同,但它们已经是不同的 commits
了。如果直接从 master
执行 rebase
的话。这就导致 master
上之前的两个最新 commit
被剔除了。如果这两个 commit
之前已经在中央仓库存在,这就会导致没法 push
了。
reset
reset
用来重置 HEAD
以及它所指向的 branch
的位置。
reset --hard HEAD^
之所以起到了撤销commit
的效果,是因为它把HEAD
和它所指向的branch
一起移动到了当前commit
的父commit
上,从而起到了「撤销」的效果。Git 的历史只能往回看,不能向未来看,所以把
HEAD
和branch
往回移动,就能起到撤回commit
的效果。
无参数:保留工作目录,并清空暂存区
reset
如果不加参数,那么默认使用 --mixed
参数。它的行为是:保留工作目录,并且清空暂存区。
也就是说,工作目录的修改、暂存区的内容以及由
reset
所导致的新的文件差异,都会被放进工作目录。简而言之,就是「把所有差异都混合(mixed)放在工作目录中」。
--hard
:重置工作目录
reset --hard
会在重置 HEAD
和 branch
的同时,重置工作目录里的内容。
当你在 reset
后面加了 --hard
参数时,你的工作目录里的内容会被完全重置为和 HEAD
的新位置相同的内容。换句话说,就是你的未提交的修改会被全部擦掉。
reset --hard
不仅可以撤销提交,还可以用来把 HEAD
和 branch
移动到其他的任何地方。
git reset --hard branch2
--soft:保留工作目录
reset --soft
会在重置 HEAD
和 branch
时,保留工作目录和暂存区中的内容,并把重置 HEAD
所带来的新的差异放进暂存区。
问题处理
git reset恢复指定版本代码后,再无法提交到远程库;git status提示出现2个分支不同提交
错误提示:Your branch and 'origin/master' have diverged, and have 1 and 1 different commits each, respectively
# 从远程仓库拉取更新,并且用rebase的方式合并到当前分支上等同于( git fetch + git rebase origin/master)
git pull --rebase origin master
# 把内容提交到远程仓库
git push origin master
checkout
可以使用checkout来切换分支
git checkout 分支名称
checkout
并不止可以切换 branch
。checkout
本质上的功能其实是:签出( checkout )指定的 commit
。
git checkout 分支名称
的本质,其实是把 HEAD
指向指定的 branch
,然后签出这个 branch
所对应的 commit
的工作目录。
所以同样的,checkout
的目标也可以不是 branch
,而直接指定某个 commit
:
git checkout HEAD^^
git checkout master~5
git checkout 78a4bc
git checkout 78a4bc^
checkout 和 reset
相同点:checkout
和 reset
都可以切换 HEAD
的位置。
不同点:reset
在移动 HEAD
时会带着它所指向的 branch
一起移动,而 checkout
不会。当你用 checkout
指向其他地方的时候,HEAD
和 它所指向的 branch
就自动脱离了。
checkout
有一个专门用来只让 HEAD
和 branch
脱离而不移动 HEAD
的用法
# 执行这行代码,Git 就会把 HEAD 和 branch 脱离,直接指向当前 commit
git checkout --detach
restore
取消暂存
git restore --staged <已被暂存的文件名>
撤销对文件的修改,将它还原成上次提交时的样子
git restore <文件名>
请务必记得这是一个危险的命令。 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它。 除非你确实清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。
stash
临时存放工作目录的改动。
在 Git 中,stash
指令可以帮你把工作目录的内容全部放在你本地的一个独立的地方,它不会被提交,也不会被删除,你把东西放起来之后就可以去做你的临时工作了,做完以后再来取走,就可以继续之前手头的事了。
具体说来,stash
的用法很简单。当你手头有一件临时工作要做,需要把工作目录暂时清理干净,那么你可以
git stash
这个时候你的工作目录的改动就被清空了,所有改动都被存了起来。然后你就可以从你当前的工作分支切到其他分支,等重新切回这个分支之后,操作:
# 之前存储的东西就都回来了
git stash pop
注意:没有被 track 的文件(即从来没有被 add 过的文件不会被 stash 起来,因为 Git 会忽略它们。如果想把这些文件也一起 stash,可以加上
-u
参数,它是--include-untracked
的简写。就像这样:git stash -u
reflog
这个指令可以处理分支被误删想恢复的问题。
reflog
是 "reference log" 的缩写,使用它可以查看 Git 仓库中的引用的移动记录。如果不指定引用,它会显示 HEAD
的移动记录。
假如你误删了 dev
这个分支,那么你可以查看一下 HEAD
的移动历史:
git reflog
从图中可以看出,HEAD
的最后一次移动行为是「从 dev
移动到 master
」。而在这之后,dev
就被删除了。所以它之前的那个 commit
就是 dev
被删除之前的位置了,也就是第二行的 6b8a52a
。
# 切换回 6b8a52a,然后重新创建 dev。这样刚删除的 dev 分支就找回来了
git checkout 6b8a52a
git checkout -b dev
注意:不再被引用直接或间接指向的
commit
会在一定时间后被 Git 回收,所以使用reflog
来找回删除的branch
的操作一定要及时,不然有可能会由于commit
被回收而再也找不回来。
查看其他引用的reflog
reflog
默认查看 HEAD
的移动历史,除此之外,也可以手动加上名称来查看其他引用的移动历史,例如:
git reflog master
进阶用法
修正commit / amend
修正最新commit
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。
可以修改之后,在提交一个 commit
,不过还有一个更加优雅和简单的解决方法:可以运行带有 --amend
选项的提交命令来重新提交
commit --amend
做的事就是它的字面意思:对最新一条 commit
进行修正。
"amend" 是「修正」的意思。在提交时,如果加上
--amend
参数,Git 不会在当前commit
上增加commit
,而是会把当前commit
里的内容和暂存区(stageing area)里的内容合并起来后创建一个新的commit
。与其说是修复旧提交,倒不如说是完全用一个 新的提交 替换旧的提交。从效果上来说,就像是旧有的提交从未存在过一样,它并不会出现在仓库的历史中。
修补提交最明显的价值是可以稍微改进你最后的提交,而不会让“啊,忘了添加一个文件”或者 “小修补,修正笔误”这种提交信息弄乱你的仓库历史。
修正其他commit
如果不是最新的 commit
写错,就不能用 commit --amend
来修复了,而是要用 rebase
。不过需要给 rebase
也加一个参数:-i
。
rebase -i
是rebase --interactive
的缩写形式,意为「交互式 rebase」所谓「交互式 rebase」,就是在
rebase
的操作执行之前,你可以指定要rebase
的commit
链中的每一个commit
是否需要进一步修改。
# 把当前 commit(HEAD 所指向的 commit) rebase 到 HEAD 之前 2 个的 commit 上
git rebase -i HEAD^^
# 在修复完成之后,就可以用 rebase --continue 来继续 rebase 过程,把后面的 commit 直接应用上去
git rebase --continue
说明:在 Git 中,有两个「偏移符号」:
^
和~
。
^
的用法:在commit
的后面加一个或多个^
号,可以把commit
往回偏移,偏移的数量是^
的数量。例如:master^
表示master
指向的commit
之前的那个commit
;HEAD^^
表示HEAD
所指向的commit
往前数两个commit
。
~
的用法:在commit
的后面加上~
号和一个数,可以把commit
往回偏移,偏移的数量是~
号后面的数。例如:HEAD~5
表示HEAD
指向的commit
往前数 5 个commit
。
丢弃commit
丢弃最新的commit
语法:git reset --hard 目标commit
例如:
# 撤销最新的提交
git reset --hard HEAD^
HEAD 表示 HEAD^ 往回数一个位置的
commit
。你被撤销的那条提交并没有消失,只是你不再用到它了。如果你在撤销它之前记下了它的
SHA-1
码,那么你还可以通过SHA-1
来找到他它。
丢弃其他commit
和上面的修正一样,可以使用rebase来处理。(在编辑界面中删除想撤销的 commit
)
比如,想撤销倒数第二条 commit
git rebase -i HEAD^^
# 可以查看log是否生效
git log
撤销提交
rebase
加上 --onto
选项之后,可以指定 rebase
的「起点」。
一般的 rebase
,告诉 Git 的是「我要把当前 commit
以及它之前的 commit
s 重新提交到目标 commit
上去,这其中,rebase
的「起点」是自动判定的:选取当前 commit
和目标 commit
在历史上的交叉点作为起点。
# 在 rebase 命令中直接剔除想撤销的 commit
git rebase --onto
--onto
参数后面有三个附加参数:目标commit
、起点commit
(注意:rebase 的时候会把起点排除在外)、终点commit
。
示例
# 以倒数第二个 commit 为起点(起点不包含在 rebase 序列里),branch1 为终点,rebase 到倒数第三个 commit 上
git rebase --onto HEAD^^ HEAD^ branch1
修正已push的commit
-
如果是自己使用的分支
【解决方案】:把写错的
commit
修改或者删除掉,然后再push
上去。git push origin 分支名称 -f
这个时候会出现预料中的冲突,希望用本地的内容覆盖掉中央仓库的内容。所以可以选择强行push(
-f
是--force
的缩写,意为「忽略冲突,强制push
」)如果是master或者是别人的分支,则一定不要强制push,否则会覆盖掉被人的提交。
-
如果已合并到master
【解决方案】:增加一个新的提交,把之前提交的内容抹掉。
【例如】:你增加了一行代码,你希望撤销它,那么你就做一个删掉这行代码的提交;如果你删掉了一行代码,你希望撤销它,那么你就做一个把这行代码还原回来的提交。这个时候可以使用
revert
指令# 这行代码的意思是,增加一条新的 commit,它的内容和倒数第二个 commit 是相反的,从而和倒数第二个 commit 相互抵消,达到撤销的效果 git revert HEAD^
在 revert
完成之后,把新的 commit
再 push
上去,这个 commit
的内容就被撤销了。
它和前面所介绍的撤销方式相比,最主要的区别是,这次改动只是被「反转」了,并没有在历史中消失掉,你的历史中会存在两条 commit
:一个原始 commit
,一个对它的反转 commit
。
打标签
Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0
、 v2.0
等等)。
列出标签
# 列出所以标签
git tag
# 列出1.8.5 系列标签
git tag -l "v1.8.5*"
创建标签
Git 支持两种标签
-
轻量标签(lightweight)
它很像一个不会改变的分支——它只是某个特定提交的引用。
# git tag <标签名> git tag v1.4-temp # 查看标签信息 git show v1.4-temp
-
附注标签(annotated)
附注标签是存储在 Git 数据库中的一个完整对象, 它们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard (GPG)签名并验证。 通常会建议创建附注标签,这样你可以拥有以上所有信息。但是如果你只是想用一个临时的标签, 或者因为某些原因不想要保存这些信息,那么也可以用轻量标签。
# 指定 -a 选项创建附注标签 # -m 选项指定了一条将会存储在标签中的信息。 如果没有为附注标签指定一条信息,Git 会启动编辑器要求你输入信息。 git tag -a v1.4 -m "my version 1.4" # 查看标签信息 git show v1.4
后期打标签
要在那个提交上打标签,你需要在命令的末尾指定提交的校验和(或部分校验和)
git tag -a v1.2 9fceb02
共享标签
默认情况下,git push
命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样——你可以运行 git push origin <tagname>
。
# 推送指定标签
git push origin v1.4
# 推送所有标签
git push origin --tags
删除标签
删除掉本地仓库上的标签, git tag -d <tagname>
git tag -d v1.4-temp
删除远程标签
git push origin --delete <tagname>
检出标签
切换到指定标签,如果你做了某些更改然后提交它们,标签不会发生变化, 但你的新提交将不属于任何分支,并且将无法访问,除非通过确切的提交哈希才能访问。
git checkout v2.0.0
因此,如果你需要进行更改,比如你要修复旧版本中的错误,那么通常需要创建一个新分支
git checkout -b version2 v2.0.0
历史记录
查看历史记录
git log
# 列出最近两周的所有提交
git log --since=2.weeks
不传入任何参数的默认情况下,git log
会按时间先后顺序列出所有的提交,最近的更新排在最上面。
这个命令会列出
- 每个提交的 SHA-1 校验(commit)
- 作者的名字和电子邮件地址(Author)
- 提交时间以及提交说明。(Date)
查看详细历史
git log -p
# -2代表只显示最近的两次提交
git log -p -2
-p
是--patch
的缩写,通过-p
参数,你可以看到每一个commit
的每一行改动,很适合用于代码 review
查看简要统计
git log --stat
如果你只想大致看一下改动内容,但并不想深入每一行的细节(例如你想回顾一下自己是在哪个
commit
中修改了games.txt
文件),那么可以把选项换成--stat
--stat
选项会在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。 在每次提交的最后还有一个总结
格式化查看log
--pretty,使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。
# 仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。
git log --pretty=oneline
git log --pretty=format:"%h - %an, %ar : %s"
# `--graph`在日志旁以 ASCII 图形显示分支与合并历史。
git log --pretty=format:"%h %s" --graph
git log --pretty=format
常用的选项
- %H:提交的完整哈希值
- %h:提交的简写哈希值
- %T:树的完整哈希值
- %t:树的简写哈希值
- %P:父提交的完整哈希值
- %p:父提交的简写哈希值
- %an:作者名字
- %ae:作者的电子邮件地址
- %ad:作者修订日期(可以用 --date=选项 来定制格式)
- %ar:作者修订日期,按多久以前的方式显示
- %cn:提交者的名字
- %ce:提交者的电子邮件地址
- %cd:提交日期
- %cr:提交日期(距今多长时间)
- %s:提交说明
查看具体commit
git show
查看任意一个commit
git show 5e68b0d8
在
show
后面加上这个commit
的引用(branch
或HEAD
标记)或它的SHA-1
码
看指定 commit 中的指定文件
# 在 commit 的引用或 SHA-1 后输入文件名
git show 5e68b0d8 demo.txt
看未提交的内容
- 显示暂存区和上一条提交之间的不同
# 这条指令可以让你看到「如果你立即输入 git commit,你将会提交什么」
git diff --staged
或者
git diff --cached
- 显示工作目录和暂存区之间的不同
# 这条指令可以让你看到「如果你现在把所有文件都 add,你会向暂存区中增加哪些内容」
git diff
- 工作目录和上一条提交之间的不同,它是上面这二者的内容相加
# 这条指令可以让你看到「如果你现在把所有文件都 add 然后 git commit,你将会提交什么」
git diff HEAD
查看某个远程仓库
# git remote show <remote>
git remote show origin
它同样会列出远程仓库的 URL 与跟踪分支的信息。 这些信息非常有用,它告诉你正处于
master
分支,并且如果运行git pull
, 就会抓取所有的远程引用,然后将远程master
分支合并到本地master
分支。 它也会列出拉取到的所有远程引用。
.gitignore
.gitignore文件用于排除不想被管理的文件和目录。文件中 #
打头的是注释文件,其他的都是对忽略文件的配置。
.gitignore
的格式规范如下:
- 所有空行或者以
#
开头的行都会被 Git 忽略。 - 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
- 匹配模式可以以(
/
)开头防止递归。 - 匹配模式可以以(
/
)结尾指定目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(
!
)取反。
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf
tip: 当你忘记添加 .gitignore
文件,不小心把一个很大的日志文件或一堆没用的文件添加到了暂存区,你可以这样做(这样不会删除文件,只是会让git不在继续跟踪)
# 移除README.md
git rm --cached README.md
# 移除 log/ 目录下扩展名为 .log 的所有文件
git rm log/\*.log
# 移除所有名字以 ~ 结尾的文件。
git rm \*~
GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore
文件列表, 你可以在 github.com/github/giti… 找到它。这是一份适用前端项目的.gitignore文件
/[demo]/*
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Editor directories and files
.vscode/*
!.vscode/settings.json
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
Pull Request
Pull Request 并不是 Git 的内容,而是一些 Git 仓库服务提供方(例如 GitHub)所提供的一种便捷功能,它可以让团队的成员方便地讨论一个 branch
,并在讨论结束后一键合并(Merge pull request)这个 branch
到 master
。
参考资料