建立自己的网站怎么样做,网站开发用php还pyt h on,桂林北站有核酸检测点吗,什么是自主设计网站本文涵盖了你在使用Git的绝大多数时间里会用到的所有基础命令。学完之后#xff0c;你应该能够配置并初始化Git仓库、开始或停止跟踪文件、暂存或者提交更改。我们也会讲授如何让Git忽略某些文件和文件模式#xff0c;如何简单快速地撤销错误操作#xff0c;如何浏览项目版本… 本文涵盖了你在使用Git的绝大多数时间里会用到的所有基础命令。学完之后你应该能够配置并初始化Git仓库、开始或停止跟踪文件、暂存或者提交更改。我们也会讲授如何让Git忽略某些文件和文件模式如何简单快速地撤销错误操作如何浏览项目版本历史并查看版本之间的差异以及如何向远程仓库推送或从中拉取数据。 在本文中,我们将在命令行中使用Git。一方面是因为命令行是唯一可以执行所有Git命令的地方大多数GUI出于简化的目的只实现了Git的部分功能,如果你知道如何使用命令行,那大概也能猜出如何使用GUI;不过反过来可就不一定了。另一方面尽管图形化客户端的选择属于个人喜好问题但命令行工具是所有的Git用户都拥有的。 一、获取Git仓库
建立Git项目的方法主要有两种
1把现有的项目或者目录导入到Git中2从服务器上克隆现有的Git仓库
1.1、在现有目录中初始化Git仓库 要想在Git中对现有项目进行跟踪管理只需进入项目目录并输入
$ git init 这会创建一个名为.git的子目录。这个子目录包含了构成Git仓库骨架的所有必需文件。但此刻Git尚未跟踪项目中的任何文件。 如果你打算着手对现有文件(非空目录)进行版本控制,那么就应该开始跟踪这些文件并进行初次提交。对需要跟踪的文件执行几次git add命令 然后输入git commit命令即可
$ git add *.c
$ git add LICENSE
$ git commit -m initial project version 稍后我们会逐一解释这些命令的含义。现在你的Git仓库已经包含了这些被跟踪的文件并进行了初次提交。
1.2、克隆现有仓库 如果需要获取现有仓库的一份副本(比如这是你想参与的一个项目),可以使用git clone命令。如果你熟悉其他版本控制系统(比如Subversion),就会注意到这个命令是“clone 而不是“checkout”。这是一个很重要的差异因为Git会对服务器仓库的几乎所有数据进行完整复制而不只是复制当前工作目录。git clone默认会从服务器上把整个项目历史中每个文件的所有历史版本都拉取下来。实际上如果你的服务器磁盘损坏你通常可以用任何客户端计算机上的Git仓库副本恢复服务器[如果这样的话服务器端的钩子设置( server-side hook )也许会丢失但全部的版本数据都会恢复如初]。 克隆仓库需要使用git clone [url]命令。 例如要克隆Git的链接库Libgit2,可以像下面这样做
$ git clone https://github.com/libgit2/libgit2 这会创建一个名为libgit2的新目录并在其中初始化.git目录然后将远程仓库中的所有数据拉取到本地并检出最新版本的可用副本。进入新的libgit2目录中会看到所有项目文件已经准备就绪。 如果想将项目克隆到其他名字的目录中可以把目录名作为命令行选项传入
$ git clone https ://github.com/libgit2/libgit2 mylibgit 这一条命令与上一条命令功能相同只是目标目录的名称变成了mylibgit。 Git可以用几种不同的协议传输数据。上一个例子使用的是http://协议,除此之外也可以使用git://协议或者是SSH传输协议(如userserver:path/to/repo.git)。
二、在Git仓库中记录变更 你现在拥有了一个真正的Git仓库并检出了项目文件的可用副本。下一 步就是做出一些更改当项目到达某个需要记录的状态时向仓库提交这些变更的快照。 请记住工作目录下的每一个文件都处于两种状态之一已跟踪( tracked )或未跟踪( untracked )。已跟踪的文件是指上一次快照中包含的文件。这些文件又可以分为未修改、已修改或已暂存三种状态。而未跟踪的文件则是工作目录中除去已跟踪文件之外的所有文件,也就是既不在上一次快照中也不在暂存区中的文件。当你刚刚完成仓库克隆时所有文件的状态都是已跟踪且未修改的因为你刚刚把它们检出而没有做出过任何改动。 如果修改了文件它们在Git中的状态就会变成已修改这意味着自从上次提交以来文件已经发生了变化。你接下来要把这些已修改的文件添加到暂存区,提交所有已暂存的变更随后重复这个过程。 2.1 查看当前文件状态 检查文件所处状态的主要工具是git status命令。如果在克隆仓库后立即执行这个命令就会看到类似下面的输出
$ git status
On branch master
nothing to commit, working directory clean 上述输出说明你的项目工作目录是干净的。也就是说工作目录下没有任何已跟踪的文件被修改过。Git也没有找到任何未跟踪的文件否则这些文件会被列出。最后该命令还会显示当前所处的分支,告诉你现在所处的本地分支与服务器上的对应的分支没有出现偏离。就目前而言我们一直处在默认的master分支。 现在让我们把一个简单的README文件添加到项目中。如果之前项目中不存在这个文件那么这次执行git status就会 看到这个未跟踪的文件
$ echo My Project README
$ git status
On branch master
Untracked files:
(use git add file... to include in what will be committed)README
nothing added to commit but untracked files present (use git add to track) 可以看到新的README文件处于未跟踪状态因为git status输 出时把这个文件显示在“Untracked files (未跟踪的文件)条目下。未跟踪的文件就是Git在上一次快照(提交)中没有发现的文件。Git并不会主动把这些文件包含到下一次提交的文件范围中除非你明确告诉Git你需要跟踪这些文件。这样做是为了避免你不小心把编译生成的二进制文件或者其他你不想跟踪的文件包含进来。需要让Git跟踪该文件才能将README加入。
2.2 跟踪新文件 可以使用git add命令让Git开始跟踪新的文件。执行以下命令来跟踪README文件
$ git add README
此时如果重新执行查看项目状态的命令就可以看到README文件已处于跟踪状态并被添加到暂存区等待提交
$ git status
On branch master
Changes to be conmitted:
(use git reset HEAD file... to unstage)new file: README 在“Changes to be commited (等待提交的更改)标题下列出的就是已暂存的文件。如果现在提交那么之前执行git add时的文件版本就会被添加到历史快照中。回想一下在早先执行git init时你执行的下一个命令就是git add (files) 这条命令就是让Git开始跟踪工作目录下的文件。git add命令接受一个文件或目录的路径名作为参数。如果提供的参数是目录该命令会递归地添加该目录下的所有文件。
2.3 暂存已修改的文件 这次让我们来更改一个已跟踪的文件。假如你更改了之前已经被Git跟踪的CONTRIBUTING.md文件此时再执行git status命令 会看到类似下面的输出:
$ git status
On branch master
Changes to be comnitted:(use git reset HEAD file... to unstage)new file:README
Changes not staged for connit:(use git add file... to update what will be committed)(use git checkout .. file... to discard changes in working directory)nodified: CONTRIBUTING.md CONTRIBUTING.md文件会出现在名为“Changes not staged for commit (已更改但未添加到暂存区)的区域中,这表示处于跟踪状态的文件在工作目录下已被修改,但尚未被添加到暂存区。要想暂存这些文件需要执行git add命令。git add是一个多功能命令,既可以用来跟踪新文件也可以用来暂存文件它还可以做其他的一些事比如把存在合并冲突的文件标记为已解决。所以把git add命令看成“添加内容到下一次提交中”而不是“把这个文件加入到项目中”更有助于理解该命令。现在让我们执行git add命令将CONTRIBUTING.md添加到暂存区然后重新执行git status:
$ git add CONTRIBUTING.md
$ git status
On branch master
Changes to be comnitted:(use git reset HEAD file... to unstage )new file: READMEmodified: CONTRIBUTING.md 上面列出的这两个文件都已暂存并将进入下一个提交中。假设你在这时想起来在提交之前还要再对CONTRIBUTINGmd做一个小小的修改。 于是你打开文件做出改动然后准备提交。 不过让我们先来再执行一次git status
$ vim CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:(use git reset HEAD file... to unstage)new file: READMEnodified: CONTRIBUTING.md
Changes not staged for commit:(use git add file... to update what wlll be committed)(use git checkout -- file... to discard changes in working directory)modified: CONTRIBUTING.md 这是怎么回事?现在CONTRIBUTING.md文件竟然同时出现在了已暂存和未暂存的列表中。这怎么可能呢?其实在暂存一个 文件时Git保存的是你执行git add时文件的样子。如果你现在执行git commit命令进行提交包含在这次提交中的CONTRIBUTING.md是你上次执行git add命令时的文件版本而不是现在工作目录中该文件的当前版本。所以如果在执行了git add之后又对已添加到暂存区的文件做了修改就需要再一次执行git add将文件的最新版本添加到暂存区
$ git add CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:(use git reset HEAD file... to unstage)new file: READMEnodified: CONTRIBUTING.md
2.4 显示更简洁的状态信息 虽然git status命令的输出信息很全面但也着实冗长。对此Git也提供了一个显示简短状态的命令行选项使你可以以一种更为紧凑的形式查看变更。执行git status -s或者git status --short就可以看到类似下面的效果。
$ git status -sM README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt 未被跟踪的新文件旁边会有一个?? 标记已暂存的新文件会有A标记而已修改的文件则会有一个M标记等等。实际上,文件列表旁边的标记是分成两列的左列标明了文件是否已暂存而右列表明了文件是否已修改。以上面的命令行输出为例工作目录下的README文件已被修改但还没有被暂存。另一个lib/simplegt.rb 文件是已修改而且已暂存的状态。而Rakefile文件则是已修改并被添加到暂存区之后又被修改过因此暂存区和工作区都包含了该文件的变更。
2.5 忽略文件
很多时候你并不希望某一类文件被Git自动添加甚至不想这些文件被显示在未跟踪的文件列表下面。这些文件一般是自动生成的文件(比如日志文件)或是由构建系统创建的文件。在这种情况下,可以创建名为.gitignore的文件,在其中列出待匹配文件的模式。下面是一个.gitignore文件的例子:
$ cat .gitignore
*.[oa]
*~ 其中第一行告诉Git忽略所有以 .o 或 .a 结尾的文件这些都是构建代码的过程中所生成的对象和归档文件。第二行则是告诉Git忽略所有以波浪号(~)结尾的文件, Emacs等许多文本编辑器都会将其标记为临时文件。你也可以让Git忽略log目录、tmp目录、pid目录以及自动生成的文档等。最好在开始工作前配置好gitignore文件,这样你就不会意外地把不想纳入Git仓库的文件提交进来了。 可以写入.gitignore文件中的匹配模式的规则如下
空行或者以#开始的行会被忽略支持标准的glob模式以斜杠(/)开头的模式可用于禁止递归匹配以斜杠(/)结尾的模式表示目录以感叹号(!)开始的模式表示取反 glob模式类似于shell所使用的简化版正则表达式。具体来讲星号(* )匹配零个或更多字符[abc]匹配方括号内的任意单个字符(在这个例子里是a、b或c), 而问号(?)则匹配任意单个字符。在方括号中使用短划线分隔两个字符( 例如[0-9] )的模式能够匹配在这两个字符范围内的任何单个字符(在这个例子里是0到9之间的任何数字)。你还可以用两个星号匹配嵌套目录比如a/**/z能够匹配a/z、a/b/z 和a/b/c/z等。 下面是另一个.gitignore文件的例子:
*.a #忽略.a类型的文件
!lib.a #仍然跟踪lib.a,即使上一行指令要忽略.a类型的文件
/TODO #只忽略当前目录的TODO文件 而不忽略子目录下的TODO
build/ #忽略build/目录下的所有文件
doc/*.txt #忽略doc/notes.txt而不忽略doc/server/arch.txt
doc/**/*.pdf # 忽略doc/目录下的所有.pdf文件
2.6 查看已暂存和未暂存的变更 如果git status命令的输出信息对你来说太过泛泛你想知道修改的具体内容而不仅仅是你更改了哪些文件,这时可以使用git diff命令。我们将稍后讲解git diff的细节现在只需知道它基本上可以用来解决两个问题哪些变更还没有被暂存?哪些已暂存的变更正待提交?尽管git status也可以通过列举文件名的方式大致回答上述问题但git diff则会显示出你具体添加和删除了哪些行。换句话说git diff的输出是补丁( patch )。 假设你又编辑并暂存了README文件,之后更改了CONTRIBUTING.md但没有暂存它。如果你现在执行git status命令那么又会看到类似下面的输出
$ git status
On branch master
Changes to be conmitted:(use git reset HEAD file... to unstage)new file: README
Changes not staged for commit:(use git add file... to update what will be committed)(use git checkout .. file... to discard changes in working directory)modified: CONTRIBUTING.md 要查看尚未添加到暂存区的变更直接输入不加参数的git diff命令:
$ git diff
diff --git a/CONTRIBUTING.nd b/CONTRIBUTING.nd
index 8ebb991. .643e24f 100644
--- a/CONTRIBUTING.mdb/CONTRIBUTING.nd
00 -65,7 65,8 0 branch directly, things can get nessy.
Please include a nice description of your changes when you submit your PR;
if we have to read the whole diff to figure out why youre contributing
in the first place, youre less likely to get feedback and have your change
-merged in.
merged in. Also, split your changes into conprehensive chunks if your patch is
longer than a dozen lines.
If you are starting to work on a particular area, feel free to subnit a PR
that highlights your work in progress (and note in the PR title that its 这条命令会将当前工作目录下的内容与暂存区的内容作对比。对比的结果就显示了有哪些还没有暂存的新变更。 如果你想看看有哪些已暂存的内容会进入下一次提交可以使用git diff --staged命令”。这条命令会将暂存的变更与上一次提交的内容相比较
$ git diff --staged
diff --git a/README b/README
new file mode 100644
index 000000. .03902a1
--- /dev/nullb/README-0,0 1
My Project请注意执行git diff本身并不会显示出自从上一次提交以来所有的变更而只会显示出还没有进入暂存区的那些变更。如果你已经把所有变更添加到了暂存区git diff不会有任何输出这会让人摸不着头脑。 再看另一个例子如果暂存了CONTRIBUTING.md之后又对它做出了修改可以用git diff命令来观察已暂存和未暂存的变更:
$ git add CONTRIBUTING.md
$ echo # test line CONTRIBUTING.nd
$ git status
On branch master
Changes to be conmitted:(use git reset HEAD file... to unstage)modifled: CONTRIBUTING.md
Changes not staged for commit:(use git add file... to update what will be conmitted)(use git checkout -- file... to discard changes in working directory)modified: CONTRIBUTING.md
2.7 提交变更 现在你的暂存区已经准备妥当可以提交了。请记得所有未暂存的变更都不会进入到提交的内容中,这包括任何在编辑之后没有执行git add命令添加到暂存区的新建的或修改过的文件。 这些文件在提交后状态并不会发生变化仍然是已修改的状态。举个例子假设你上次执行git status命令时看到所有变更都已暂存并等待提交。这时最简单的提交方式就是执行git commit命令
$ git commit 执行这条命令后就会打开你所选择的文本编辑器。(默认会采用shel的环境变量SEDITOR所指定的文本编辑器通常是Vim或者Emacs。 文本编辑器会显示以下文本(以Vim为例):
# Please enter the cormit nessage for your changes. Lines starting
# with # will be ignored, and an enpty nessage aborts the connit.
# On branch master
# Changes to be comnitted:
# new file: README
# nodified: CONTRIBUTING.md
#
~
~
~
.git/COMMIT_EDITMSG 9L, 283C 可以看出默认的提交信息会包括被注释掉的git status命令的最新输出结果在最上边还有一行是空行。你既可以删掉这些注释并输入自己的提交信息也可以保留这些注释以帮助你记住提交的具体内容。(若需要记下更详细的更改记录可以给git commit加上-v参数。这样会把这次提交的差异比对显示在文本编辑器中让你可以看到要提交的具体变更。)当你退出编辑器时Git会移除注释内容和差异比对把剩下的提交信息记录到所创建的提交中。 完成上述提交还有另一种方式那就是直接在命令行上键人提交信息。这需要给git commit命令加上-m选项:
$ git commit -m Story 182: Fix benchnarks for speed
[naster 463dc4f] Story 182: Fix benchmarks for speed
2 files changed, 2 insertions()
create node 100644 README 你终于完成了自己的首次提交可以看到命令输出中包含了和该提交本身相关的一些信息提交到哪个分支( master ).提交的SHA-1校验和是多少( 463dc4f )。改动了多少个文件以及源文件新增和删除了多少行的统计信息。 请记住提交时记录的是暂存区中的快照。任何未暂存的内容仍然保持着已修改状态。你可以再次提交这些内容将其纳入到版本历史记录中。每次提交时都记录了项目的快照日后可以用于比对或恢复。
2.8 跳过暂存区 在按照你的要求精确地生成提交内容时暂存区非常有用但就工作流而言它有时显得有点过于繁琐了。如果你想要跳过暂存区直接提交Git为你提供了更快捷的途径。给git commit命令传入-a选项就能让Git自动把已跟踪的所有文件添加到暂存区然后再提交这样你就不用再执行git add了
$ git status
On branch master
Changes not staged for commit:
(use git add file... to update what will be comnitted)
(use git checkout .. file... to discard changes in working directory)modified: CONTRIBUTING.md
no changes added to conmit (use git add and/or git commit -a)
$ git commit -a -m added new benchnarks
[master 83e38c7] added new benchnarks
1 file changed, 5 insertions(), 0 deletions(-) 注意在上面的例子中提交前不再需要执行git add来添加CONTRIBUTING.md文件了。
2.9 移除文件 要从Git中移除某个文件你需要把它先从已跟踪文件列表中移除(确切地说是从暂存区中移除)然后再提交。git rm会帮你完成这些操作另外该命令还会把文件从工作目录中移除这样下一次你就不会在未跟踪文件列表中看到这些文件了。 如果你只是简单地把文件从你的工作目录移除而没有使用git rm 那么在执行git status时会看到文件出现在Changes not staged for commit”区域(也就是未暂存区域)
$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with origin/master.
Changes not staged for conmit:(use git add/rm file... to update what will be committed)(use git checkout -- file... to discard changes in working directory)deleted: PROJECTS.nd
no changes added to commit (use git add and/or git commit -a) 如果你这时执行git rm, Git才 会把文件的移除状态记录到暂存区
$ git rm PROJECTS.md
rm PROJECTS.md
$ git status
On branch raster
Changes to be committed:(use git reset HEAD file... to unstage)deleted: PROJECTS.md 下一次提交的时候这个文件就不存在了也不会再被Git跟踪管理。如果你更改了某个文件并已经把它加入到了索引当中(已暂存),要想让Git移除它就必须使用 -f 选项强制移除。这是为了防止没有被记录到快照中的数据被意外移除而设立的安全特性,因为这样的数据被意外移除后无法由Git恢复。 另一件你可能想做的有用的事情是把文件保留在工作目录,但从暂存区中移除该文件。换句话说你也许想将文件保留在硬盘上但不想让Git对其进行跟踪管理。如果你忘了向.gitignore 文件中添加相应的规则不小心把一个很大的日志文件或者一些编译生成的.a文件添加进来上述做法尤其有用。只需使用--cached选项即可
$ git rm --cached README 你可以将文件、目录和文件的glob模式传递给git rm命令。这意味着你可以像下面这样:
$ git rm log/\*.log 请注意在*前面的反斜杠(\)是必需的这是因为shell和(Git先后都要处理文件名扩展。上述命令会移除log目录中所有扩展名为.log的文件。或者你也可以像下面这样:
$ git rm \*~ 这条命令会移除所有以~结尾的文件。
2.10 移动文件 Git与很多其他版本控制系统不同它并不会显式跟踪文件的移动。如果你在Git中重命名了文件仓库的元数据并不会记录这次重命名操作。不过Git非常聪明它能推断出究竟发生了什么。至于Git究竞如何检测到文件的移动操作我们稍后再谈。 因此当你看到Git有一个mv命令时就会有点搞不明白了。在Git中可以执行下面的命令重命名文件:
$ git mv file_from file_to 结果没有问题。实际上执行了这条命令后再去查看状态的话就会发现Git识别出了重命名后的文件:
$ git mv README.md README
$ git status
On branch master
Changes to be committed:
(use git reset HEAD file... to unstage)
renaned:README.md - README 其实这相当于执行了下面的三条命令:
$ mv README.md README
$ git rm README.md
$ git add README 不管你是用Git的mv命令还是直接给文件改名Git都能推断出这是重命名操作。唯一的区别是git mv只需键入一条命令而不是三条命令所以会比较方便。更重要的是你可以用任何你喜欢的工具或方法来重命名文件然后在提交之前再执行Git的add和rm命令。
三、查看提交历史 此小节不细讲命令了解即可因为我们平时开发的时候使用相关的GUI工具会比较更方便。 在完成了几次提交或者克隆了一个已有提交历史的仓库之后你可能想要看看历史记录。可以使用git log命令来实现这是最基础却又最强大的一条命令。 默认不加参数的情况下git log会按照时间顺序列出仓库中的所有提交其中最新的提交显示在最前面。如你所见和每个提交一同列出的还有它的SHA-1校验和、作者的姓名和邮箱、提交日期以及提交信息。 git log有很多不同的选项 可以直观地展示出所需内容。现在我们来看一些最常用的选项。最有用的一个选项是-p, 它会显示出每次提交所引人的差异。你还可以加上-2参数只输出最近的两次提交。
四、撤销操作 在任何时刻你都有可能想撤销之前的操作。现在让我们来看看撤销更改所用到的几个基本工具。有些撤销操作是不可逆的所以请务必当心。在Git中误操作导致彻底丢失工作成果的情景并不多见而这就是其中之一。 有一种撤销操作的常见使用场景是提交之后才发现自己忘了添加某些文件,或者写错了提交信息。如果这时你想重新尝试提交可以使用--amend选项:
$ git commit --amend 上述命令会提交暂存区的内容。如果你在上次提交之后并没做出任何改动(比如你在上次提交后立即执行上面的命令),那么你的提交快照就不会有变化,但你可以改动提交信息。和之前提交时一样,这次也会启动提交信息编辑器有所不同的是打开的编辑器中会显示上次提交的信息。你可以像之前-样编辑保存后就会覆盖之前的提交信息。 举一个例子如果你提交后才意识到忘记了添加某个之前更改过的文件,可以执行类似下面的操作:
$ git commit -m initial commit
$ git add forgotten_file
$ git commit --amend 最终只是产生了一个提交因为第二个提交命令修正了第一个提交的结果。
4.1 撤销已暂存的文件 接下来的两节内容会演示如何管理暂存区和工作目录的变更。好消息是我们用来显示上述两个区域状态的命令同样也会告诉我们如何撤销这两个区域的变更。举例来说假设你更改了两个文件想要分两次提交却不小心键入了git add *把这两个文件都添加到了暂存区。这时你该如何把它们从暂存区移出呢?其实git status命令会提示你该如何做:
$ git add *
$ git status
On branch master
Changes to be committed:(use git reset HEAD file... to unstage)renamed: README.md READMEmodified: CONTRIBUTING.md 在Changes to be committed”正下方显示的提示是“使用git reset HEAD file... 命令把文件移出暂存区”。所以我们就用提示的办法把CONTRIBUTING.md文件移出暂存区:
$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:(use git reset HEAD file... to unstage)renamed: README.md - README
Changes not staged for conit:(use git add file... to update what will be comitted)(use git checkout .. file... to discard changes in working directory)modified: CONTRIBUTING.md 这条命令看起来有点奇怪,但是它确实管用。CONTRIBUTING.md又恢复到了已修改但未暂存的状态。 注意尽管git reset加 上--hard参数时很危险但是如果你使用上述例子中的命令来操作工 作目录中的文件就不会被改动。也就是说执行不加选项的git reset是安全的 它只更改暂存区。 4.2 撤销对文件的修改 如果你突然发现自己不再需要对CONTRIBUTING.md文件所做的更改,这时该怎么办?如何轻松地撤销修改并把文件恢复到上次提交时的状态(或是刚克隆仓库后的状态或是一开始它在工作目录时的状态) ?幸运的是git status这次也会告诉你该怎么做。在上一个例子的输出内容中未暂存的工作区如下所示:
Changes not staged for commit: (use git add file... to update what will be cormitted)(use git checkout .. file... to discard changes in working directory)modified: CONTRIBUTING.md
上述输出很明确地告诉了你如何舍弃对文件的更改。让我们照它说的做:
$ git checkout .. CONTRIBUTING.md
$ git status
On branch master
Changes to be conmitted:(use git reset HEAD file... to unstage)renamed: README.md README
可以看出之前所做的修改已经恢复了。 注意重要的是要了解git checkout -- [file]是一条危险的命令。执行该命令后任何对[file]文件做出的修改都会丢失因为上述命令用之前版本的文件做了覆盖。除非你确信不再需要这些文件否则不要用这个命令。 请记住在Git中提交的任何变更几乎总是可以进行恢复。哪怕是在已删除的分支上的提交或是被--amend覆盖的提交都可以进行恢复。但是任何未提交过的变更一旦丢失就很可能再也找不回来了。
五、远程仓库的使用 要参与任何一个Git项目的协作你需要了解如何管理远程仓库。远程仓库是指在互联网或其他网络上托管的项目版本仓库。你可以拥有多个远程仓库,而对于其中每个仓库,你可能会拥有只读权限或者读写权限。要同别人协作,就要管理这些远程仓库,在需要分享工作成果时,向其推送数据从中拉取数据。管理远程仓库需要知道如何添加远程仓库、移除无效的远程仓库。管理各种远程分支和设置是否跟踪这些分支,等等。在本节中,我们会讲解上述远程仓库管理技巧中的一部分。
5.1 显示远程仓库 要查看已经设置了哪些远程仓库请使用git remote命令。该命令会列出每个远程仓库的简短名称。在克隆某个仓库之后你至少可以看到名为origin的远程仓库这是Git给克隆源服务器取的默认名称。
$ git clone https://github.com/schacon/ticgit
Cloning into ticgit ...
remote: Reusing existing pack: 1857 done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB| 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin你也可以使用-v参数这样会显示出Git存储的每个远程仓库对应的URL:
$ git remote -v
Origin https://github.com/schacon/ticgit (fetch)
Origin https://github.com/schacon/ticgit (push) 如果你有不止一个远程仓库上面的命令会把它们都列出来。
5.2 添加远程仓库 如何显式地添加仓库。要添加一个远程仓库 并给它起一个简短名称以便引用可以执行命令
git remote add [shortname] [url]
例如
$ git remote
origin
$ git renote add pb https://github.com/paulboone/ticgit
$ git renote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push) 现在你可以在命令行中使用pb字符串替代完整的URL。比如要获取Paul拥有而你还没有的全部数据可以执行git fetch pb命令
$ git fetch pb
renote: Counting objects: 43, done.
renote: Compressing objects: 100% (36/36) done.
renote: Total 43 (delta 10)reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
Fron https ://github. con/paulboone/ticgit
* [new branch] master - pb/master
* [new branch] ticgit - pb/ticgit 现在你可以在本地用pb/master的名称访问到Paul的master分支,还可以把它和你的一个分支合并或是检出一个本地分支便于检查其中的更改。
5.3 从远程仓库获取和拉取数据 正如上面所见要从远程项目获取数据可以执行:
$ git fetch [remote-nane] 这条命令会从远程仓库中获取所有本地仓库没有的数据。在执行上述命令后你就可以在本地引用远程仓库包含的所有分支并可以在任何时候合并或检查这些分支。 当你克隆仓库时克隆命令会自动添加远程仓库的地址并取名为“origin”。 当随后执行git fetch origin时 会获取到所有自上一次克隆( 或获取)之后被推送到服务器端的新增的变更数据。请注意git fetch命令只会把数据拉取到本地仓库然而它并不会自动将这些数据合并到本地的工作成果中也不会修改当前工作目录下的任何数据。在准备好之后需要手动将这些数据合并到本地内容中。 如果你有一个跟踪着某个远程分支的本地分支可以使用git pull命令来自动获取远程数据并将远程分支合并入当前本地分支。这种简单易用的工作流可能会更适合你。而且默认情况下git clone命令会自动设置你的本地master分支使其跟踪被克隆的服务器端的master分支(或是叫其他名称的默认远程分支)。这时候执行git pull就会从被克隆的服务器上获取更新的数据然后自动尝试将其合并入当前工作目录下的本地数据。
5.4 将数据推送到远程仓库 当你的项目进行到某个阶段,需要与他人分享你的工作成果时,就要把变更推送到远程仓库去。用到的命令很简单: git push [remote-name] [branch-name]。 如果想把本地的master分支推送到远程的origin服务器上(再说一次Git克隆操作会自动使用上面两个名称作为默认设置),那么可以执行以下命令把任意提交推送到服务器端:
$ git push origin master 上述命令能够正常工作的前提是必须拥有克隆下来的远程仓库的写权限并且克隆后没有任何其他人向远程仓库推送过数据。如果别人和你都克隆了这个仓库而他先推送你后推送那么你的这次推送会直接被拒绝。你必须先拉取别人的变更将其整合到你的工作成果中,然后才能推送。
5.5 检查远程仓库
要查看关于某一远程仓库的更多信息可使用git remote show [remote -name]命令。如果给该命令提供一个仓库的短名称比如origin,就会看到如下输出:
$ git remote show origin
* renote origin
Fetch URL: https://github.com/schacon/ticgit
Push URL: https://github.com/schacon/ticgit
HEAD branch: master
Remote branches:
master tracked
dev-branch tracked
Local branch configured for git pull:master merges with renote master
Local ref configured for git push:master pushes to master (up to date) 上述命令列出了远程仓库的URL地址以及每个分支的跟踪信息。这条命令会输出一些很有帮助的信息比如告诉你在naster分支上执行git pull会获取到所有的远程引用然后自动合并入master分支。它还显示了拉取下来的所有远程引用的信息。
5.6 删除和重命名远程仓库 可以用git remote rename来重命名远程仓库。如果想要把pb重命名为paul,可以用git remote rename命令来实现如下所示。
$ git remote rename pb paul
$ git remote
origin
paul 值得一提的是 上述操作也会更改远程分支的名称。先前的pb/master分支现在变成了paul/ master。 有时出于某种原因需要删除某个远程仓库地址比如当你迁移了服务器地址或是不再使用某一仓库镜像又或是某个参与者退出协作时,就可以使用git remote rm命令,如下所示。
$ git remote rm paul
$ git remote
origin
六、标记 就像大多数版本控制系统一样Git可以把特定的历史版本标记为重要版本。其典型应用场景是标出发布版本(v1.0等)。在本节中你可以学到如何列举所有可用的标签如何创建新的标签以及不同标签之间的差异。
6.1 列举标签
在Git中列举可用标签的操作很简单只需键入git tag即可:
$ git tag
v0.1
v1.3
这条命令会按字母顺序列出所有的标签。列举的顺序先后和标签的重要性无关。
你还可以按照某个特定匹配模式搜索标签。举例来说Git的源代码仓库包括超过500个标签。
如果你只想查看1.8.5系列的标记版本可以执行以下命令。
$ git tag -l v1.8.5*
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
6.2 创建标签 Git使用的标记主要有两种类型轻量( lightweight )标签和注释( annotated)标签。 轻量标签很像是一个不变的分支——它只是一个指向某次提交的指针。 注释标签则会作为完整的对象存储在Git数据库中。Git会计算其校验和,除此之外还包含其他信息比如标记者( tagger)的名字、邮箱地址和标签的创建时间还有标记消息( tagging message),另外还可以利用GNU Privacy Guard ( GPG )对它们进行签名和验证。一般推荐创建注释标签这样可以包含上述所有信息。但如果你需要的只是一个临时标签或者由于某些原因不需要包含那些额外信息也可以用轻量标签。
6.3 注释标签
创建注释标签很简单只需要执行带有-a选项的tag命令即可:
$ git tag -a v1.4 -m my version 1.4
$ git tag
v0.1
v1.3
v1.4 -m选项指定了标记信息它会伴随着标签一起被存储。如果你没有为注释标签指定标记消息。Git会打开文本编辑器以便你进行输入。 执行git show命 令可以看到标签数据以及对应的提交:
$ git show v1.4
tag v1.4
Tagger: Ben Straub benstraub.cc
Date:
Sat May 3 20:19:12 2014 -0700
my version 1.4
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon schacongee-mail. com
Date: Mon Mar 17 21:52:11 2008 -0700
changed the verison nunber 上述命令的输出显示了标记者信息、提交被标记的日期以及注释消息最后是提交信息。
6.4 轻量标签 另一种用来标记提交的方法是使用轻量标签。这种标签基本上就是把提交的校验和保存到文件中除此之外不包含其他任何信息。创建一个轻量标签时不需要使用-a. -s或-m选项:
$ git tag v1.4 - lw
$ git tag
v0.1
V1.3
v1.4
v1.4-1w
V1.5 如果你现在在这个标签上执行git show,除了提交信息之外不会看到别的标签信息。
$ git show v1.4-lw
comnit ca82a6df f817ec66f44342007202690a93763949
Author: Scott Chacon schacongee-nail.com
Date:
Mon Mar 17 21:52:11 2008 -0700
changed the verison number
6.5 共享标签 默认情况下git push命令不会把标签传输到远程服务器上。在创建了标签之后你必须明确地将标签推送到共享服务器上。这个过程有点像推送分支对应的命令是git push origin [tagnane]。
$ git push origin v1.5
Counting objects: 14 done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done .
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done. .
Total 14 (delta 3) reused 0 (delta 0)
To gitgithub. com: schacon/simplegtt.git
* [new tag]
V1.5 - V1.5 如果你有很多标签需要一次性推送 可以使用git push命令的--tags选项。这会把所有服务器上还没有的标记都推送过去。
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes |日bytes/s, done.
Total 1 (delta 0), reused θ (delta 0)
To gitgithub . com: schacon/sinplegit.git
曲[new tag]
v1.4 - V1.4
* [new tag]
v1.4-1w - v1.4-1w 执行完上述命令后如果其他人此时对仓库执行克隆或拉取操作他们也能够得到所有的标签。
6.6 检出标签. 你是无法在Git中真正检出一个标签的这是因为标签无法移动。如果想将某个版本的仓库放入像是标签的工作目录中可以使用git checkout -b [br anchnane] [tagname ]在特定标签上创建一个新的分支
$ git checkout -b version2 v2.0.0
Switched to a new branch version2 如果你执行上面的操作并完成了提交,那么version2分支会和你的v2.0.0标签略有不同,因为它携带了新的变更所以要小心操作。