git 文件的状态
对于任何一个文件,在 Git 内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。
- 已提交:表示该文件已经被安全地保存在本地数据库中了;
- 已修改:表示修改了某个文件,但还没有提交保存;
- 已暂存:表示把已修改的文件放在下次提交时要保存的清单中。
Git 管理项目时,文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库。
基本的 Git 工作流程如下:
-
在工作目录中修改某些文件。
-
对修改后的文件进行快照,然后保存到暂存区域。
-
提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。
工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪。 已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区。而所有其他文件都属于未跟踪文件。
分支
在 Git 中提交时,会保存一个提交(commit)对象,该对象包含一个指向暂存内容快照的指针,包含本次提交的作者等相关附属信息,包含零个或多个指向该提交对 象的父对象指针:首次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先。 当使用 git commit新建一个提交对象前,Git 会先计算每一个子目录(本例中就是项目根目录)的校验和,然后在 Git 仓库中将这些目录保存为树(tree)对象。之后 Git 创建的提交对象,除了包含相关提交信息以外,还包含着指向这个树对象(项目根目录)的指针,如此它就可以在将来需要的时候,重现此次快照的内容了。 Git 是如何知道你当前在哪个分支上工作的呢?其实答案也很简单,它保存着一个名为 HEAD 的特别指针。请注意它和你熟知的许多其他版本控制系统(比如 Subversion 或 CVS)里的 HEAD 概念大不相同。在 Git 中,它是一个指向你正在工作中的本地分支的指针(译注:将 HEAD 想象为当前分支的别名。)。
跟踪远程分支 从远程分支 checkout 出来的本地分支,称为_跟踪分支(tracking branch)_。跟踪分支是一种和远程分支有直接联系的本地分支。在跟踪分支里输入git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。
git 命令
在工作目录中初始化新仓库,要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录执行
git init
从现有仓库克隆,克隆仓库的命令格式为
git clone [url]
git clone git://github.com/schacon/grit.git
这会在当前目录下创建一个名为“grit”的目录,其中包含一个 .git 的目录,用于保存下载下来的所有版本记录,然后从中取出最新版本的文件拷贝。
如果希望在克隆的时候,自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:
git clone git://github.com/schacon/grit.git mygrit
Git 支持许多数据传输协议。之前的例子使用的是 git:// 协议,不过你也可以用 http(s):// 或者user@server:/path.git表示的 SSH 传输协议。
config
Git 提供了一个叫做 git config 的工具(译注:实际是 git-config 命令,只不过可以通过 git 加一个名字来呼叫此命令。),专门用来配置或读取相应的工作环境变量。而正是由这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:
-
/etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用--system 选项,读写的就是这个文件。
-
~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用--global 选项,读写的就是这个文件。
-
当前项目的 git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以.git/config 里的配置会覆盖/etc/gitconfig 中的同名变量。
配置你个人的用户名称和电子邮件地址
(这两条配置很重要,每次 Git 提交时都会引用这两条信息,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录)
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
如果只是想给某个 git repo 自定义 config 可以把 global 修改为 local,e.g:
git config --local user.name "John Doe"
git config --local user.email johndoe@example.com
(上面的--local可以省掉,默认就是 local)
设置的是默认使用的文本编辑器,比如使用 vim 编辑 commit message
git config --global core.editor vim
指定差异分析工具。比如要改用 vimdiff
git config --global merge.tool vimdiff
开启 diff3, 可在冲突时同时查看 local(本地分支), remote(远端分支), common ancestors(共同祖先) 的差异:
git config --global merge.conflictstyle diff3
alias
Git 并不会推断你输入的几个字符将会是哪条命令,不过如果想偷懒,少敲几个命令的字符,可以用 git config 为命令设置别名。来看看下面的例子:
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 config --global alias.cp cherry-pick
git config --global alias.pop 'stash pop --index'
git config --global alias.stash=stash --include-untracked
git config --global color.ui true
git config --global alias.tree 'log --graph --decorate --pretty=oneline --abbrev-commit'
现在,如果要输入 git commit 只需键入 git ci 即可。
使用这种技术还可以创造出新的命令,比方说取消暂存文件时的输入比较繁琐,可以自己设置一下:
git config --global alias.unstage 'reset HEAD --'
git config --global alias.cc 'cherry-pick --continue'
颜色显示diff
git config --global color.ui true
查看配置信息:
git config --list
获取帮助:
$ git help
$ git help config
跟踪新文件
git add {file path}
git add 的潜台词就是把目标文件快照放入暂存区域,也就是 add file into staged area,同时未曾跟踪过的文件标记为需要跟踪。这是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。
检查当前文件状态
git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD to unstage)
#
# new file: README
#
只要在 “Changes to be committed” 这行下面的,就说明是已暂存状态。如果此时提交,那么该文件此时此刻的版本将被留存在历史记录中。 文件如果出现在 “Changed but not updated” 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行git add 命令.运行了git add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来!!!
查看文件变化
git diff
此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
查看已经暂存起来的文件和上次提交时的快照之间的差异:
git diff --cached
查看某个文件在不同分支上的变化(会显示两个分支基于公共组件的所有变化):
git diff develop master {file}
git diff develop..master {file}
只显示 feature 分支相对于 base 分支新增的 diff 变更:
git diff base...feature
commit
git commit
可以用 -m 参数后跟提交说明的方式,在一行命令中提交更新:
git commit -m "fix bug 110"
注意,提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。
跳过使用暂存区域
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。Git 提供了一个跳过使用暂存区域的方式,只要在提交的时候,给 git commit 加上-a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤:
git commit -a -m 'added new benchmarks'
默认如果没有修改是无法生成 commit 的,如果要刻意生成一个空的 commit,可以通过下面命令
git commit --allow-empty -m "empty commit"
移除文件
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。
git rm {file}
如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f(译注:即 force 的首字母),以防误删除文件后丢失修改的内容。
我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中:
git rm --cached {file}
后面可以列出文件或者目录的名字,也可以使用 glob 模式。比方说:
git rm log/\*.log
注意到星号 * 之前的反斜杠 \,因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开(译注:实际上不加反斜杠也可以运行,只不过按照 shell 扩展的话,仅仅删除指定目录下的文件而不会递归匹配。上面的例子本来就指定了目录,所以效果等同,但下面的例子就会用递归方式匹配,所以必须加反斜 杠)。此命令删除所有log/ 目录下扩展名为 .log 的文件。类似的比如:
git rm \*~
会递归删除当前目录及其子目录中所有 ~ 结尾的文件。
在 Git 中对文件改名
git mv file_from file_to
log
git log
显示最近n次log:
git log -{n}
显示每次提交的内容差异:
git log -p
将每个提交放在一行显示,这在提交数很大时非常有用。
git log --pretty=oneline
pretty参数取值另外还有 short,full和fuller 可以用,展示的信息或多或少有些不同。以及 format,可以定制要显示的记录格式,这样的输出便于后期编程提取分析,像这样:
git log --pretty=format:"%h - %an, %ar : %s" --since=108.days
列出了常用的格式占位符写法及其代表的意义
| 选项 | 说明 |
|---|---|
| %H | 提交对象(commit)的完整哈希字串 |
| %h | 提交对象的简短哈希字串 |
| %T | 树对象(tree)的完整哈希字串 |
| %t | 树对象的简短哈希字串 |
| %P | 父对象(parent)的完整哈希字串 |
| %p | 父对象的简短哈希字串 |
| %an | 作者(author)的名字 |
| %ae | 作者的电子邮件地址 |
| %ad | 作者修订日期(可以用 -date= 选项定制格式) |
| %ar | 作者修订日期,按多久以前的方式显示 |
| %cn | 提交者(committer)的名字 |
| %ce | 提交者的电子邮件地址 |
| %cd | 提交日期 |
| %cr | 提交日期,按多久以前的方式显示 |
| %s | 提交说明 |
用 oneline 或 format 时结合 --graph 选项,可以看到开头多出一些 ASCII 字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况。
git log --pretty=format:"%h %s" --graph
git log --pretty=format:"%h %an %s"
git log --pretty=format:"%h %s %an"
查询commit1与commit2之间的记录:
git log commitID1 commitID2
按补丁格式显示每个更新之间的差异:
git log -p
查看已被删除的文件的 log 修改记录:
git log -- [filename]
显示两个分支基于公共组件的节点所有的新增 log 历史:
g log dev...feature
显示feature 基于两个分支的公共祖先节点新增的 log 历史:
git log dev..feature
切换到commitId 的修改点
git checkout commitId
查看 commitId 的修改内容
git show commitid
修改最后一次提交
git commit --amend
此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。 如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:
git commit -m 'initial commit'
git add forgotten_file
git commit --amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
将某个文件从暂存区撤出
git reset HEAD {file}
恢复一个“已修改但还没有暂存的”文件:
git checkout {file}
查看当前配置有哪些远程仓库:
git remote
git remote -v //显示对应的克隆地址
添加远程仓库:
git remote add [shortname] [url]
git remote add pb git://github.com/paulboone/ticgit.git
用字串 pb 指代对应的仓库地址.比如说,要抓取所有 Paul 有的,但本地仓库没有的信息,可以运行 git fetch pb.
从远程仓库抓取数据:
git fetch [remote-name]
此命令会到远程仓库中拉取所有你本地仓库中还没有的数据。运行完成后,你就可以在本地访问该远程仓库中的所有分支,将其中某个分支合并到本地,或者只是取出某个分支,一探究竟。 如果是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。所以,git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。
如果设置了某个分支用于跟踪某个远端仓库的分支,可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。实际上,默认情况下git clone 命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)。所以一般我们运行git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中的当前分支。
如果本地有新的提交,远端也有未拉取的新提交,默认的 git pull 命令会生成一个 merge commit,这个大家工作中是非常不想看到的,建议在 pull 时加上 rebase 参数。
git pull --rebase
可以永久配置每次都是 rebase 模式来 pull 代码:
git config --global pull.rebase true
推送数据到远程仓库
git push [remote-name] [branch-name]
如果要把本地的 master 分支推送到origin 服务器上(再次说明下,克隆操作会自动使用默认的 master 和 origin 名字),可以运行下面的命令:
git push origin master
等同于origin master:master, 用本地名为master的分支去更新远程仓库中名master的分支。
用HEAD当前指向的分支去更新远程仓库中名为mybranch的分支:
git push origin HEAD:refs/for/mybranch
只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,这条命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那 你的推送操作就会被驳回。你必须先把他们的更新抓取到本地,合并到自己的项目中,然后才可以再次推送。
查看远程仓库信息
git remote show [remote-name]
除了对应的克隆地址外,它还给出了许多额外的信息。它友善地告诉你如果是在 master 分支,就可以用 git pull 命令抓取数据合并到本地。另外还列出了所有处于跟踪状态中的远端分支。
远程仓库的删除和重命名
git remote rename 命令修改某个远程仓库在本地的简短名称,比如想把 pb 改成paul,可以这么运行:
git remote rename pb paul
对远程仓库的重命名,也会使对应的分支名称发生变化,原来的 pb/master 分支现在成了 paul/master
碰到远端仓库服务器迁移,或者原来的克隆镜像不再使用,又或者某个参与者不再贡献代码,那么需要移除对应的远端仓库,可以运行 git remote rm 命令:
git remote rm paul
tag
列显已有的标签:
git tag
列出指定条件的标签,如:列出包含关键字stable的标签:
git tag -l "*stable*"
删除远端已经删除的本地tag:
git fetch --prune origin "+refs/tags/*:refs/tags/*"
新建标签
Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特 定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标 签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。
轻量级标签实际上就是一个保存着对应提交对象的校验和信息的文件。要创建这样的标签,一个 -a,-s 或 -m 选项都不用,直接给出标签名字即可:
git tag v1.4
删除标签:
git tag -d v1.4
删除远端tag:
git tag -d tagname
git push --delete origin tagname
修改远端tag的名字:
git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags
推送单个tag到远端:
git push origin <tag_name>
如果要一次推送所有本地新增的标签上去,可以使用 --tags 选项:
git push origin --tags
创建一个含附注类型的标签非常简单,用 -a (译注:取 annotated 的首字母)指定标签名字即可:
git tag -a v1.4 -m 'my version 1.4'
-m 选项则指定了对应的标签说明,Git 会将此说明一同保存在标签对象中。如果没有给出该选项,Git 会启动文本编辑软件供你输入标签说明。
git show 命令查看相应标签的版本信息,并连同显示打标签时的提交对象:
git show v1.4
签署标签,如果你有自己的私钥,还可以用 GPG 来签署标签,只需要把之前的 -a 改为 -s (译注: 取 signed 的首字母)即可:
git tag -s v1.5 -m 'my signed 1.5 tag'
Only list tags which contain the specified commit:
git tag --contains commitId
branch
设置自动将当前分支push到远端(远端分支名与本地相同),修改配置文件~/.gitconfig, as following:
[alias]
pao = "!git push --set-upstream origin \"$(git rev-parse --abbrev-ref HEAD)\""
新建分支
git branch <分支名>
这会在当前 commit 对象上新建一个分支指针,运行git branch 命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中去。
Git 是如何知道你当前在哪个分支上工作的呢?其实答案也很简单,它保存着一个名为 HEAD 的特别指针。请注意它和你熟知的许多其他版本控制系统(比如 Subversion 或 CVS)里的 HEAD 概念大不相同。在 Git 中,它是一个指向你正在工作中的本地分支的指针(译注:将 HEAD 想象为当前分支的别名。)。
切换分支
git checkout <分支名>
这样 HEAD 就指向了 <分支名>分支
要新建并切换到该分支,运行git checkout 并加上 -b 参数:
git checkout -b iss53
这相当于执行下面这两条命令:
git branch iss53
git checkout iss53
推送本地分支
要想和其他人分享某个本地分支,你需要把它推送到一个你拥有写权限的远程仓库。
git push (远程仓库名) (分支名)
git push origin serverfix
这其实有点像条捷径。Git 自动把 serverfix 分支名扩展为 refs/heads/serverfix:refs/heads/serverfix,意为“取出我在本地的 serverfix 分支,推送到远程仓库的 serverfix 分支中去”。我们将在第九章进一步介绍refs/heads/ 部分的细节,不过一般使用的时候都可以省略它。也可以运行 git push origin serverfix:serferfix 来实现相同的效果,它的意思是“上传我本地的 serverfix 分支到远程仓库中去,仍旧称它为 serverfix 分支”。
通过此语法,你可以把本地分支推送到某个命名不同的远程分支:若想把远程分支叫作awesomebranch,可以这样来推送数据:
git push origin serverfix:awesomebranch
git push will by default push all branches that have the same name on the remote. To limit this behavior to just the current branch, set this configuration option:
git config --global push.default tracking
This is to prevent accidental pushes to branches which you’re not ready to push yet.
在远程分支的基础上分化出一个新的分支来,git checkout -b [分支名] [远程名]/[分支名]:
git checkout -b serverfix origin/serverfix
这会切换到新建的 serverfix 本地分支,其内容同远程分支 origin/serverfix 一致,这样你就可以在里面继续开发了。
creates and checks out "feature" branch that tracks "origin/feature":
git checkout -t origin/feature
Once your teammate has shared a branch he or she was working on, you need to create a local branch for yourself if you intend to make changes to it. This does that and sets up tracking so that you can just git push after making changes.
Make an existing Git branch track a remote branch? Given a branch foo and a remote upstream:
git branch -u upstream/foo
Or, if local branch foo is not the current branch:
git branch -u upstream/foo foo
重命名分支
git branch -m <oldname> <newname>
If you want to rename the current branch, you can simply do:
git branch -m <newname>
删除本地分支
git branch -d <branch_name>
删除远程分支
git push [远程名] :[分支名](注意冒号有前一个空格)
git push origin :serverfix
有种方便记忆这条命令的方法:记住我们不久前见过的 git push [远程名] [本地分支名]:[远程分支名] 语法,如果省略 [本地分支],那就等于是在说“在这里提取空白然后把它变成[远程分支]”。
查看各个分支最后一个提交对象的信息
git branch -v
要从该清单中筛选出你已经(或尚未)与当前分支合并的分支,可以用 –merge 和 –no-merged 选项
git branch --merged
git branch --no-merged
合并分支
回到主分支,然后合并指定的分支:
git checkout master
git merge <branch_name>
请注意,合并时如果出现了“Fast forward”的提示。是由于当前 master 分支所在的提交对象是要并入的 hotfix 分支的直接上游,Git 只需把master 分支指针直接右移。换句话说,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。
git merge 如果可以快进, 默认就会快进, 如果需要生成一个 merge 的 commit, 需要使用 git merge --no-ff,这样总会生成一个 merge 的 commit。
显示某个 Merge Commit 的 diff:
git show -m {commit-id}
列出 MR 修改的文件列表:
git log -m -1 --name-only --pretty="format:" {commit-id}
将某个commit的修改应用到当前分支,注意这个操作会移除掉之前所作未保存的修改,执行前请先git stash
git cherry-pick commit_id
查看冲突文件不同分支上的差异 commit:
git log --left-right --merge <file>
或者
git log --left-right HEAD...MERGE_HEAD <file>
上面命令可加上 -p 参数同时显示每个差异 commit 的 diff, 快速查看冲突的行都是哪些 commit 修改的.
本地代码库回滚
回滚到commit-id,将commit-id之后提交的commit都去除:
git reset --hard commit-id
将最近n次的提交回滚:
git reset --hard HEAD~n
将上次的commit恢复到待commit的状态,这样不会丢失之前的修改
git reset --soft HEAD~1
重置本地的分支与远端分支一致,比如要重置本地分支foo与远端同名分支一致:
git fetch origin
git checkout foo
git reset --hard origin/foo
stash
切换分支时,保存已修改但不想commit的内容
To see which stashes you’ve stored:
git stash list
stash@{0}: WIP on luliang/git_test: 5ef91af Merge branch 'luliang/filemanager_send_by_email_bugs' into 'develop'
stash@{1}: WIP on luliang/git_test: 5ef91af Merge branch 'luliang/filemanager_send_by_email_bugs' into 'develop'
stash@{2}: WIP on luliang/git_test: 5ef91af Merge branch 'luliang/filemanager_send_by_email_bugs' into 'develop'
从上面可见,该分支暂存过3次,stash@{0}是最新的。
git stash apply stash@{1}
NOTE: 1. 如果一个文件暂存后,又做了修改,重新reapply会失败。2. 如果要reapply的文件前后没有发生变化就会提示nothing to commit, working directory clean。
丢弃最近的一次暂存记录:
git stash drop
恢复最近的一次 stash 保存的内容:
git stash pop
相当于以下两条命令:
git stash apply
git stash drop
delete all of your Git stashes at once:
git stash clear
显示最近一次暂存的diff
git stash show -p
重置最近恢复的暂存变化为之前状态:
git stash show -p | git apply -R
恢复到之前的status , The changes to your files were reapplied, and the file you staged will be restaged with --index.
git stash apply --index
stash 包含新增文件
git stash --include-untracked
stash 增加注释
git stash save "comment"
revert
revert最近的第n+1个commit:
git revert HEAD~n
revert 指定commitid:
git revert {commitid}
revert出现冲突后,需要解决冲突,解决完成后add 冲突文件,然后:
git revert --continue
也可以放弃解决冲突:
git revert --abort
To undo a merge that was already pushed:
git revert -m 1 commit_hash
查看git 的操作记录:
git reflog
30eb940 HEAD@{1}: commit: 降级 gradle 版本统一使用 java8编译
f33fc1b HEAD@{2}: commit: 升级core 版本
5d062a1 HEAD@{3}: commit (amend): SummaryInfo 改成 Device
可以配合 checkout回退到对应的操作点
how revert already "git commit --amend"?
git branch fixing-things HEAD@{1}
git reset fixing-things
忽略本地修改的文件(永远不会commit),有时候需要自定义某个被git 跟踪的文件,但是又不想提交入库。可以通过下面命令来忽略对它的修改:
git update-index --assume-unchanged path/to/file.txt
或者
git update-index --skip-worktree path/to/file.txt
如果需要重新跟踪这个文件:
git update-index --no-assume-unchanged path/to/file.txt
或者
git update-index --no-skip-worktree path/to/file.txt
已经被跟踪的文件或目录如果要忽略,不仅要添加到.gitignore,而且需要执行下面命令:
git rm -r --cached .
git add .
git commit -m "remove untracked files"
获取 git 仓库的网址url
git config --get remote.origin.url
合并多个commit为一个 commit,假设要合并最后的2个提交:
git rebase –i HEAD~2
将第二个pick修改为squash或者s,然后输入":wq”退出。
将某个 commit 的修改保存成 patch 文件:
git format-patch -1 <commitId>
list all the commits present in feature branch which are not present in the master.
git cherry -v master feature
浅clone代码:
- 浅clone
git clone -b develop --depth=1 xxx.git
- 拉取所以历史记录
git fetch --unshallow
- 拉取所有远程分支
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin