摘要:Git初学教程
一、Git常用命令
1.1 获取Git仓库
- git init:创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件都是 Git 仓库的骨干,但这仅仅是一个初始化的操作,你的项目中的文件并没有被追踪。
- git clone:克隆现有的仓库,例如:
git clone https://github.com/libgit2/libgit2
。
1.2 记录每次更新到仓库
- git status:查看哪些文件处于什么状态。
- git status -s/–short:状态简览。由于
git status
命令输出十分详细,但是其用语相对繁琐,故使用该命令可以以简洁的形式查看更改,得到一种格式更为紧凑的输出。 - git add:跟踪新文件,对所指定的文件进行追踪,并处于暂存状态,
git add *.c
,其中*.c
表示某个文件。 - git diff:以文件补丁的格式更加具体地显示那些行发生了改变,比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
- git diff --staged/–cached:比对已暂存文件与最后一次提交的文件差异。
- git commit:提交更新。将暂存区中的内容提交,在此之前应当确认还有什么已修改或新建的文件没有
git add
过,否则提交的时候不会记录这些尚未暂存的变化。 - git commit --amend:这条命令会将最后一次的提交信息载入到编辑器中供你修改。 当保存并关闭编辑器后,编辑器会将更新后的提交信息写入新提交中,它会成为新的最后一次提交。以新的改进后的提交来 替换掉旧有的最后一次提交。
- git commit -m “提交信息”:将提交信息与命令放在同一行。值得注意的是:提交时记录的是放在暂存区域的快照,任何还未暂存文件的仍然保持已修改的状态,可以在下一次提交时纳入版本管理。每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。
- git commit -a:自动将所有已经追踪过的文件暂存起来一并提交,直接跳过了
git add
操作。 - git rm:移除文件。要从 Git 中移除某个文件,就必须要从以跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。
- git rm -f:强制删除。
-f
为强制删除选项,如果要删除之前修改过后已经放入到暂存区的文件,则必须加上-f
。这是一种安全特性,用于防止误删尚未添加到快照的数据,这样的数据不能被 Git 恢复。 - git mv file_from file_to:移动文件。重命名操作。
1.3 查看提交历史
-
git log:查看提交历史。
-
git log -p/–patch :查看提交历史。它会显示每次提交所引入的差异(按补丁的格式输出)。同样也可以限制显示的日志条目数量,例如:
git log -p -2
表示只显示最近的两次提交。 -
git log --stat:查看每次提交的简略信息。当进行代码审查,或者快速浏览某个搭档的提交所带来的变化的时候,这个参数就非常有用了。
--stat
:选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或者被添加了,在每次提交的最后还有个总结。 -
git log --pretty:该选项可以使用不同默认格式的方式展示提交历史。
-
git log --pretty=format:"%h %s" --graph:
--graph
选项表示在日志旁以ASCII图形显示分支与合并历史。 -
git log --online --decorate --graph --all:会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。
1.4 撤销操作
- git commit --amend:有时候我们提交完了才发现漏掉几个文件没有添加,或者提交信息写错了,此时就可以使用该命令来重新提交。换句话说,就是新的提交替换了旧的提交。
- git reset HEAD .c:将暂存的 .c 文件取消暂存,变为修改未暂存的状态。
- git checkout – .c:该命令可以做到:不想保留 .c 文件的修改,将该文件还原成上次提交时的样子(或者刚克隆完的样子,或者刚把它放入工作目录时的样子)。但该命令同样也是一个危险的命令,你对该文件在本地的任何修改都会消失,Git 会用最近提交的版本覆盖掉它。除非你确实想清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。
1.5 远程仓库的使用
- git remote:查看你已经配置的远程仓库服务器,它会列出你指定的每一个远程服务器的简写。
- git remote -v:会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL 。如果你的远程仓库不止一个,该命令会将他们全部列出。
- git remote add :表示添加一个新的远程仓库,同时指定一个方便使用的简写。例如:
git remote add pb https://github.com/paulboone/ticgit
,现在你就可以在命令行中使用字符串pb来代替整个 URL。再者,如果你想要拉取 Paul 的仓库中但你没有的信息,可以直接运行git fetch pb
。 - git fetch:访问远程仓库,从中拉取所有你还没有的数据。必须注意:
git fetch
命令只会将数据下载到你的本地仓库,但是它并不会自动合并或者修改你当前的工作,当准备好时应必须手动将其合并你的工作。 - git pull:自动抓取后合并该远程分支到当前分支。通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前的所在的分支。
- git push :推送到远程仓库。当你想要分享你的项目时,必须将其推送到上游的。
- git remote show :查看某个远程仓库的更多信息。
- git remote rename:修改一个远程仓库的简写名。
- git remote remove/rm:删除一个远程仓库。
1.6 打标签
- git tag:列出标签。如果对某个标签感兴趣,可以直接运行
git tag -l/--list "v1.8.5"
,这样就可以获得标签中含有"v1.8.5"
版本系列的。 - git tag -a v1.4 -m “my version 1.4”:创建附注标签。
-m
选项指定了一条将会存储在标签中的信息。 - git tag v1.4-lw:创建轻量标签。轻量标签本质上是将提交校验和存储到一个文件中,但并没有保存任何其他的信息。
- git tag -a v1.2 <某个提交版本>:给某个版本打上v1.2的标签。
- git push origin :将创建完标签后你必须显示地推送标签到共享服务器。
- git push origin --tags:将所有 不在远程仓库服务器上的标签全部传送到那里,这样,当其他人从仓库克隆或者拉取,他们也能得到你的那些标签。
- git tag -d :删除你本地仓库上的标签。改命令不会从任何远程仓库中移除这个标签。
- git push origin --delete :删除远程仓库中的对应的标签。
- git checkout :检出标签。其实就是转换分支。如果你想查看某个标签所指向的文件版本,可以使用改命令,但是这会使你的仓库处于“分离头指针(detached HEAD)”的状态。
二、Git分支简介
2.1 分支的新建与合并–分支管理
- git branch testing:创建 testing 新分支。
- git branch:会得到当前所有分支的一个列表,而在某个分支上的
*
代表目前所在的分支,也就是HEAD
指针所指向的分支。 - git branch -v:查看每一个分支的最后一次提交。
- git branch --merged:查看哪些分支已经合并到当前分支。
- git branch --no-merged:查看所有包含未合并工作的分支。
- HEAD:表示在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将
HEAD
想象为当前分支的别名)。 - git checkout testing:表示切换到新建的testing分支上去,此时
HEAD
就指向 testing 分支了。 - git checkout -b test:表示创建一个新分支test,并立即切换过去。
- git merge hotfix:将 hotfix 分支与当前分支合并。
- git branch -d hotfix:删除 hotfix 分支。
-D
选项表示强制删除。
2.2 远程分支
- git ls-remote :显示地获得远程引用的完整列表。
- git remote show :获得远程分支的更多的信息。
- git push :显示地推送远端的某个分支上。例如:
git push origin serverfix
。等同于git push origin serverfix:serverfix
,推送本地的severfix
分支作为远程仓库的severfix
分支。 - git fetch:从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并。
- git fetch origin:抓取到新的远程跟踪分支时,本地不会自动生成一份可编辑的副本,只有再运行
git merge origin/serverfix
命令,将这些工作合并到当前所在的分支,才能编辑。 - git pull:查找当前分支所跟踪的服务器与分支, 从服务器上抓取数据然后尝试合并入那个远程分支。在大多数情况下它的含义是一个
git fetch
紧接着一个git merge
命令。 - git checkout -b severfix origin/serverfix:建立自己的
serverfix
分支,并且起点位于origin/severfix
。 - git branch -vv:查看设置的所有跟踪分支。
- git push origin --delete serverfix:删除远程
serverfix
分支。
2.3 Git分支–变基
-
变基的原理:使用
rebase
命令将提交到某一分支上的所有修改都移至另一分支上,就好像"重新播放"一样。例如:$ git checkout experiment $ git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command
-
git rebase :直接将主题分支变基到目标分支上。这样能够省去你先切换到
server
分支,再对其执行变基命令的多个步骤。例如:git rebase master server
,表示将server
分支中的修改变基到master
上;然后就可以快速合并主分支master
了:git checkout master; git merge server
,至此,就将server
分支中的修改全部整合至master
主分支里了。随后就可以删除该server
分支了:git branch -d server
。这样一来,整体上的提交历史就变成了一条直线了。 -
git rebase -i HEAD~3:如果想要修改最近三次提交信息。在
HEAD~3..HEAD
范围内的每一个修改了提交信息的提交及其 所有后裔 都会被重写。 -
变基的风险:变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用
git rebase
命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。应当遵守的一条准则:如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。 -
git pull --rebase:因为
git pull
将相同的内容又重新合并了一次,生成了一个新的提交,而使用--rebase
选项并不会产生一个commit
提交,而是直接将别的分支直接重放,不会多出你所不知道的commit
,使得commit
看起来很自然。
三、服务器上的Git
3.1 协议
Git 可以使用四种不同的协议来传输资料:本地协议(Local),HTTP 协议,SSH(Secure Shell)协议及 Git 协议。
-
本地协议:
-
HTTP协议:
-
SSH协议:
-
Git 协议:
3.2 在服务器上搭建Git
- git clone --bare my_project my_project.git:通过克隆你的仓库
my_project
来创建一个新的裸仓库,裸仓库的目录名以.git
结尾。 - scp -r my_project.git user@git.example.com:/srv/git:复制你的裸仓库来创建一个新的仓库。
四、分布式 Git
4.1 分布式工作流程
- 集中式工作流:
- 集成管理者工作流:
- 主管与副主管工作流:
4.2 向一个项目贡献
-
提交准则:
-
项目提交时常用命令:
4.3 维护项目
- git apply /tmp/patch-ruby-client.patch:将该补丁整合应用到项目中。
- git apply --check 0001-seeing-if-this-helps-the-gem.patch:检查该
.patch
补丁文件是否可以顺利应用。 - git am 0001-limit-log-function.patch:将补丁合并应用在项目中,等价于
git apply
。 - git log contrib --not master:查看
contrib
分支中而不是master
分支中的提交日志。
五、GitHub
5.1 对 GitHub 项目作出贡献
6.2 GitHub - 对项目做出贡献
- GitHub流程:
- 派生一个项目(fork)
- 从
master
分支创建一个新的分支 - 提交一些修改来改进项目
- 将这个分支推送到 GitHub 上
- 创建一个拉取请求(pull request)
- 讨论,根据实际情况继续修改
- 项目的拥有者合并或关闭你的拉取请求
- 将更新后的
master
分支同步到你的派生中
六、Git 工具
- git add -i/–interactive:Git 进入一个交互式终端模式。当你在修改了大量文件后,希望将这些改动能拆分为若干提交而不是混杂在一起成为一个提交时,这个工具就很有用。通过这种方式,可以确保提交是逻辑上独立的变更集,同时也会使其他开发者在与你工作时很容易地审核。
- git add -p/–patch:将部分文件暂存
- git reset --patch:利用补丁的模式来重置文件
- git checkout --patch:部分检出文件
- git stash:贮藏工作。有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态, 而这时你想要切换到另一个分支做一点别的事情。贮藏(stash)会处理工作目录的脏的状态——即跟踪文件的修改与暂存的改动——然后将未完成的修改保存到一个栈上, 而你可以在任何时候重新应用这些改动(甚至在不同的分支上)。等价于
git stash push
。--keep-index
选项表示:Git 不仅要贮藏所有已暂存的内容,同时还要将它们保留在索中;--include-untracked
或-u
选项表示:Git 也会贮藏任何未跟踪文件。 然而,在贮藏中包含未跟踪的文件仍然不会包含明确 忽略 的文件。 要额外包含忽略的文件,请使用--all
或-a
选项;--patch
表示:Git 不会贮藏所有修改过的任何东西, 但是会交互式地提示哪些改动想要贮藏、哪些改动需要保存在工作目录中。
- git stash list:查看贮藏东西的列表
- git stash apply:将刚刚贮藏的工作重新应用。如果想要应用其中一个更旧的贮藏,可以通过名字指定它,像这样:
git stash apply stash@{2}
。 如果不指定一个贮藏,Git 认为指定的是最近的贮藏。--index
选项尝试应用暂存的修改; - git stash drop:移除某个贮藏的工作。等价于
git stash pop
。 - git stash branch :以你指定的分支名创建一个新分支,检出贮藏工作时所在的提交,重新在那应用工作,然后在应用成功后丢弃贮藏
- git clean:对于工作目录中一些工作或文件,你想做的也许不是贮藏而是移除。