克隆仓库
1 | git clone 远程仓库地址 [本地仓库的根目录名称] |
.git 目录
本地仓库(Local Repository),本地所有的版本信息都会存在这里。.git 所在的根目录称为 Git 的工作目录(Working Directory),它保存了你当前从仓库中签出(checkout)的内容。
可通过在工作目录下输入
git init
命令创建 .git 目录。
概念
branch
对 commit
的引用。
每一个 commit
都有一个唯一的指定方式——它的 SHA-1 校验和。两个 SHA-1 值的重复概率极低,所以可以使用这个 SHA-1 值来指代 commit
,也可以只使用它的前几位来指代它,但毕竟这种没有任何含义的字符串是很难记忆的,所以 Git 提供了「引用」的机制:使用固定的字符串作为引用,指向某个 commit
。
HEAD
对当前 commit
的引用。
每次当有新的 commit
的时候,HEAD
会转而指向最新的 commit
。
使用
checkout
、reset
等指令手动改变当前 commit 的时候,HEAD 也会一起跟过去。
总之,当前 commit
在哪里,HEAD
就在哪里,这是一个永远自动指向当前 commit
的引用,所以永远可以用 HEAD
来操作当前 commit
。
HEAD
除了可以指向 commit
,还可以指向一个 branch
,当它指向某个 branch
的时候,会通过这个 branch
来间接地指向某个 commit
。另外,当 HEAD
在提交时自动向前移动的时候,它会像一个拖钩一样带着它所指向的 branch
一起移动。
Feature Branching 工作流
任何新的功能(feature)或 bug 修复全都新建一个
branch
来写。branch
写完后,合并到master
,然后删掉这个branch
。
解决了代码分享与一人多任务的问题。
查看信息
git log
查看历史 commit
的信息,包括 commit
的 SHA-1 校验和(类似 commit
的 id),提交作者,提交时间以及提交信息。
按 q
键退出查看。
加上 -p
或 --patch
参数,可以查看每个 commit
的改动细节。
使用 --stat
参数只是查看大致的改动内容,并不会深入每一行的细节。
git status
查看工作目录当前状态,包括当前所处的 branch
,相对于 origin/branch
的位置,是否有 untracked files(未追踪的文件)等等。
untracked 状态表示 Git 本地仓库对它没有进行任何记录,你在提交的时候不会把它提交上去,查看提交历史也不会看到它,对于 Git 本地仓库来说,它是不存在的。
可通过
git add [文件名]
命令让 Git 追踪指定的 untracked 状态的文件并记录进暂存区。
git show
查看当前 commit
的改动内容。
操作
git add
可添加具体文件名参数将指定文件被改动的部分记录进暂存区。
也可添加 .
或者 all
参数将工作目录下的所有改动全部放进暂存区。
通过
add
添加进暂存区的不是文件名,而是具体的文件改动内容。
git commit
将暂存区中的内容提交到本地仓库。
可通过使用 -m "提交信息"
参数来方便地填写提交信息。
git push
把当前 branch
的位置上传到远程仓库,并把它路径上的 commit
也一并上传。
可通过添加 origin branch
参数来指定上传到远程仓库的哪一个分支。
在 Git 中(2.0 及它之后的版本),默认情况下,你用不加参数的 git push 只能上传那些之前从远端 clone 下来或者 pull 下来的分支,而如果需要 push 你本地的自己创建的分支,则需要手动指定目标仓库和目标分支(并且目标分支的名称必须和本地分支完全相同)。
push
的时候只会上传当前的branch
的指向,并不会把本地的HEAD
的指向也一起上传到远程仓库。事实上,远程仓库的HEAD
是永远指向它的默认分支(master
)的,并会随着默认分支的移动而移动。
git pull
把远程仓库上的内容取回到本地并和本地合并。
可通过添加 origin branch
参数来指定要取远程仓库的哪一个分支的内容。
git pull
这个指令的内部实现就是使用git fetch
把远程仓库的内容取下来以后再进行merge
操作。
git branch
添加分支名称参数来创建一个新的 branch
。
添加 -d 分支名
参数来删除指定的 branch
HEAD
指向的branch
不能删除。如果要删除HEAD
指向的branch
,需要先用checkout
把HEAD
指向其他地方。
由于 Git 中的
branch
只是一个对commit
的 引用,所以删除branch
的操作只会删掉这个引用,并不会删除任何的 commit。(不过如果一个commit
不在任何一个branch
的「路径」上,或者换句话说,如果没有任何一个branch
可以回溯到这条commit
,那么在一定时间后,它会被 Git 的回收机制删除掉)。
出于安全考虑,没有被合并到
master
过的branch
在删除时会失败(怕误删掉「未完成」的branch
),如果确认是要删除这个branch
(例如某个未完成的功能被团队确认永久毙掉了,不再做了),可以把-d
改成-D
进行强制删除。
git checkout
添加分支名称参数来切换 branch
(即将 HEAD
指向目标 branch
)。
可以用
git checkout -b 分支名称
来将git branch
和git checkout
两步操作合并执行。这行代码可以帮你用指定的名称创建branch
后,再直接切换过去。
git merge
添加分支名称参数来指定一个目标 commit
(branch
参数所指向的 commit
),将从目标 commit
和当前 commit
(即 HEAD
所指向的 commit
)分叉的位置起,把目标 commit
路径上的所有 commit
的内容一并应用到当前 commit
中,然后自动生成一个新的 commit
。
如果 Git 仓库处于冲突待解决的中间状态,并且你最终决定放弃这次 merge
,可以通过执行 git merge --abort
来手动取消它。
特殊情况:
如果
merge
时的目标commit
和HEAD
指向的commit
并不存在分叉,而是HEAD
领先于目标commit
,那么merge
就没必要再创建一个新的commit
来进行合并操作了,因为并没有什么需要合并的内容,在这种情况下,Git 什么也不会做,merge
只是一个空操作。如果
HEAD
和目标commit
不存在分叉,但HEAD
落后于目标commit
,那么 Git 会直接把HEAD
(以及它所指向的branch
)移动到目标commit
,这种操作有一个专有称谓,叫做 “fast-forward”(快速前移)。