git 命令的使用(二)

来源:互联网 发布:淘宝色情服务暗语 编辑:程序博客网 时间:2024/05/18 12:41

分支,合并


分支是git众多强大的特点之一。如果你使用过其他的版本控制系统,对你忘记你理解的分支是有用的,事实上,它可能更有助于把他们几乎在上下文因为这是你如何将最常被使用。当你检出不同的分支,您可以快速上下文切换来回几个不同的分支。

简而言之,你可以创建一个分支用git branch(branchname),切换分支用git checkout(branchname),记录提交快照虽然在这种背景下,然后可以轻松地来回切换。当你切换分支,Git取代你的工作目录和快照最新的承诺在那树枝所以你不必有多个目录为多个分支。你一起合并分支用git merge。你可以很容易地合并多次从同一分支随着时间的推移,或交替地你可以选择一个分支合并后立即删除。

 git checkout

切换到新的分支

git branch 命令是常用的git管理工具,可以做一系列的事情。我们将介绍最常用的几个:列出分支,建立分支和删除分支。也会介绍git checkout 切换分支,git branch list 列出活动的分支。

无参数情况下,git branch 将列出所有的本地分支。当前工作的分支将有*,如果你有着色打开,将显示当前分支在绿色。

$ git branch* master


这意味着当前我们有一个“master”分支。当你运行git init git将默认为你建立一个master分支,然而没有任何特殊的名字——你不必真的有“master”分支,但因为它是默认创建的。大多数项目都是这么做的:git branch (branchname) 建立一个新分支。所以让我们建立一个新分支,切换到它:

$ git branch testing$ git branch* mastertesting
现在,可以看到我们有一个新分支。在提交之后用这种方法建立分支,然后切换到‘testing',他会将你的工作目录恢复到你建立时的状态你可以认为它是一个书签,我们看下例子:
$ lsREADME hello.rb$ echo 'test content' > test.txt$ echo 'more content' > more.txt$ git add *.txt$ git commit -m 'added two files'[master 8bd6d8b] added two files2 files changed, 2 insertions(+), 0 deletions(-)create mode 100644 more.txtcreate mode 100644 test.txt$ lsREADME hello.rb more.txt test.txt$ git checkout testingSwitched to branch 'testing'$ lsREADME hello.rb

现在我们看到切换到’testing‘分支,我们的新文件消失了。我们可以切换回’master‘看到它们又回来了。

$ lsREADME hello.rb$ git checkout masterSwitched to branch 'master'$ lsREADME hello.rb more.txt test.txt

git branch -v

查看每个分支的上次提交

如果要查看每个分支的上次提交,我们可以使用git branch -v

$ git branch -v* master 54b417d fix javascript issuedevelopment 74c111d modify component.json filetesting 62a557a update test scripts

git checkout -b (branchname)

建立并立即切换到一个分支

大多数情况下,你回立即切换到新建的分支,然后你在这工作,待到工作得内容完成之后合并到稳定的分之上像’master‘分支。你可以简单的git branch newbranch,git checkout newbranch,但是git提供了更好的git checkout -b newbranch

$ git branch* master$ lsREADME hello.rb more.txt test.txt$ git checkout -b removalsSwitched to a new branch 'removals'$ git rm more.txtrm 'more.txt'$ git rm test.txtrm 'test.txt'$ lsREADME hello.rb$ git commit -am 'removed useless files'[removals 8f7c949] removed useless files2 files changed, 0 insertions(+), 2 deletions(-)delete mode 100644 more.txtdelete mode 100644 test.txt$ git checkout masterSwitched to branch 'master'$ lsREADME hello.rb more.txt test.txt
你可以看到,我是怎么样建立分支,删除分支上的几个文件,然会回到主分支,文件又回来了,分支之间工作是独立的,可以在他们之间切换。
在分支上工作很有用,(因为简单快捷)在完成时合并,删除。如果你没有实现它,可以方便的丢弃,回到稳定的内容之上。

git branch -d (branchname)

删除一个分支

如果你要删除一个分支(例如’tesitng‘分支),我们可以运行git branch -d (branch) 删除它。

$ git branch* mastertesting$ git branch -d testingDeleted branch testing (was 78b2670).$ git branch* master

git push (remote-name) :(branchname)

删除一个远程分支

当你完成一个任务要删除一个远程分支,你将会用到git push 命令删除远程分支。

$ git push origin :tidy-cutleryTo git@github.com:octocat/Spoon-Knife.git- [deleted] tidy-cutlery
在上面的例子里你删除了远程’tidy-cutlery‘分支。记住这种方法有个窍门:git push remote-name local-branch:remote-branch 你推送你的本地分支到远程分支,你的本地分支是空的,远程分支也就什么也没有了。

简而言之你使用git branch list 列出你当前的分支,创建新分支和删除不必要的或已经合并分支。

git merge

合并一个分支到当前分支

当你工作在一个独立的分支,你最终需要将它合并到主分支之上。你可以用git merge命令将任何分支合并到当期分支之上。让我们做一个例子:

$ git branch* masterremovals$ lsREADME hello.rb more.txt test.txt$ git merge removalsUpdating 8bd6d8b..8f7c949Fast-forwardmore.txt | 1 -test.txt | 1 -2 files changed, 0 insertions(+), 2 deletions(-)delete mode 100644 more.txtdelete mode 100644 test.txt$ lsREADME hello.rb

更复杂的合并
当然这不仅仅是简单的文件增删。git 也会合并修改文件。事实上,git很擅长这个。例如:让我们在一个分支里修改一个文件,在另一个分支里重命名并修改相同的文件,然后合并:
$ git branch* master$ cat hello.rbclass HelloWorlddef self.helloputs "Hello World"endendHelloWorld.hello
现在 我们建立一个新分支叫“chang_class” 切换到它,这样修改是独立的。我们将修改'HelloWorld' to 'HiWorld'
$ git checkout -b change_classSwitched to a new branch 'change_class'$ vim hello.rb$ head -1 hello.rbclass HiWorld$ git commit -am 'changed the class name'[change_class 3467b0a] changed the class name1 files changed, 2 insertions(+), 4 deletions(-)
所以现在我们已经提交类重命名改变“'change_class“的分支。切换回“master”分支类名称将会恢复到以前的水平,我们什么切换分支。在这里我们可以改变不同的东西(在这种情况下,输出)和同时重命名文件从hello.rb2ruby rb。
$ git checkout masterSwitched to branch 'master'$ git mv hello.rb ruby.rb$ vim ruby.rb$ git diffdiff --git a/ruby.rb b/ruby.rbindex 2aabb6e..bf64b17 100644--- a/ruby.rb+++ b/ruby.rb@@ -1,7 +1,7 @@class HelloWorlddef self.hello- puts "Hello World"+ puts "Hello World from Ruby"endend$ git commit -am 'added from ruby'[master b7ae93b] added from ruby1 files changed, 1 insertions(+), 1 deletions(-)rename hello.rb => ruby.rb (65%)

现在这些修改已经呗’master'记录。注意:类名是”helloWord“,不是”HiWord“。要包含”Hiword“修改,我们需要在'change_class'分支上合并。但是文件名变了,git会怎么做?

$ git branchchange_class* master$ git merge change_classRenaming hello.rb => ruby.rbAuto-merging ruby.rbMerge made by recursive.ruby.rb | 6 ++----1 files changed, 2 insertions(+), 4 deletions(-)$ cat ruby.rbclass HiWorlddef self.helloputs "Hello World from Ruby"endendHiWorld.hello
git 搞定它了。注意:会有合并冲突。

合并冲突
So,git合并很神奇,我们永远不会再去处理冲突,是么?不完全是的。在这种情况下,相同的代码块是编辑在不同分支没有办法让电脑来搞定它,所以我们。让我们看看另一个例子改变相同的线在两个分支。
$ git branch* master$ git checkout -b fix_readmeSwitched to a new branch 'fix_readme'$ vim README$ git commit -am 'fixed readme title'[fix_readme 3ac015d] fixed readme title1 files changed, 1 insertions(+), 1 deletions(-)
现在我们在一个分支中的readme文件修改一行。现在让我们改变相同的行用一个不同的方式回到我们的“master”分支。
$ git checkout masterSwitched to branch 'master'$ vim README$ git commit -am 'fixed readme title differently'[master 3cbb6aa] fixed readme title differently1 files changed, 1 insertions(+), 1 deletions(-)
现在见证奇迹的时刻----我讲把第一个分支合并到主分支,引起冲突。
$ git merge fix_readmeAuto-merging READMECONFLICT (content): Merge conflict in READMEAutomatic merge failed; fix conflicts and then commit the result.$ cat README<<<<<<< HEADMany Hello World Examples=======Hello World Lang Examples>>>>>>> fix_readme
你可以看到git 插入了标准的冲突标记,向svn一样。现在让我们解决冲突。可以手动修改,但是也可以使用图形界面的合并工具(kdiff3, emerge, p4merge, 等等)代替。
$ vim README # here I'm fixing the conflict$ git diffdiff --cc READMEindex 9103e27,69cad1a..0000000--- a/README+++ b/README@@@ -1,4 -1,4 +1,4 @@@- Many Hello World Examples-Hello World Lang Examples++Many Hello World Lang Examples

这里可以使用git diff查看两个文件的不同,提交修改,
$ git status -sUU README$ git add README$ git status -sM README$ git commit[master 8d585ea] Merge branch 'fix_readme'
现在我们已经成功的解决了合并冲突,提交奥了修改结果。

简而言之你使用git合并到另一分支结合上下文到当前分支。它会自动找出如何最好地结合成一个新的快照不同快照与独立的工作的两个分支。

git log

显示分支的提交历史

目前为止,我们已经提交了项目快照,在不同的分支之间切换,但是我们一旦忘记了做过什么怎么办?或者想要知道一个分支与另一份哪里不同?git 提供了一个可以显示提交信息的工具git log

要查看任何分支的按时间排列的双亲列表你可以在分支里运行git log,例如:
$ git logcommit 8d585ea6faf99facd39b55d6f6a3b3f481ad0d3dMerge: 3cbb6aa 3ac015dAuthor: Scott Chacon <schacon@gmail.com>Date: Fri Jun 4 12:59:47 2010 +0200Merge branch 'fix_readme'Conflicts:READMEcommit 3cbb6aae5c0cbd711c098e113ae436801371c95eAuthor: Scott Chacon <schacon@gmail.com>Date: Fri Jun 4 12:58:53 2010 +0200fixed readme title differentlycommit 3ac015da8ade34d4c7ebeffa2053fcac33fb495bAuthor: Scott Chacon <schacon@gmail.com>Date: Fri Jun 4 12:58:36 2010 +0200fixed readme titlecommit 558151a95567ba4181bab5746bc8f34bd87143d6Merge: b7ae93b 3467b0aAuthor: Scott Chacon <schacon@gmail.com>Date: Fri Jun 4 12:37:05 2010 +0200Merge branch 'change_class'...
To see a more compact version of the same history, we can use the --oneline option.
查看更简单的信息可以加上--oneline参数:
$ git log --oneline8d585ea Merge branch 'fix_readme'3cbb6aa fixed readme title differently3ac015d fixed readme title558151a Merge branch 'change_class'b7ae93b added from ruby3467b0a changed the class name17f4acf first commit
它会告诉我们项目开发的历史。如果提交信息是描述性的,这可以告诉我们什么变化已应用或影响了当前状态的快照。
我们还可以使用它来查看当历史被分支和合并与非常有用——图选项。这是同样的命令,但是与拓扑图形打开:
$ git log --oneline --graph* 8d585ea Merge branch 'fix_readme'|\| * 3ac015d fixed readme title* | 3cbb6aa fixed readme title differently|/* 558151a Merge branch 'change_class'|\| * 3467b0a changed the class name* | b7ae93b added from ruby|/* 17f4acf first commit

git tag

标记一个重要的历史点

如果一个点很重要,你想永远的记住这个特殊的提交,可以用git tag 标记。这个标记命令基本是一个永远有效的书签,可以在以后与其他的提交做比较。
让我们看看怎么把我们的helloword项目的1.0版本发布。使用git tag -a  (意思是做一个注释标签),也可以不用-a但是这样git 就不会记录下标记的时间,作者或者其他的信息。
$ git tag -a v1.0 
当你运行这条命令,git将会打开你的编辑器,让你输入标记信息,就像提交信息一样,。
现在,注意:什么时候运行run git log --decorate,可以看到我们的标记。
$ git log --oneline --decorate --graph* 594f90b (HEAD, tag: v1.0, master) reverted to old class name* 8d585ea Merge branch 'fix_readme'|\| * 3ac015d (fix_readme) fixed readme title* | 3cbb6aa fixed readme title differently|/* 558151a Merge branch 'change_class'|\| * 3467b0a changed the class name* | b7ae93b added from ruby|/* 17f4acf first commit
我们做跟多的提交,标记会在正确的提交之上,
我们不需要在提交时标记,然而。如果我们忘了标记一个提交,我们释放,我们可以追溯标签通过运行相同的命令,但上次提交。例如,假设我们已经提交558151发布一个(几个提交后)但忘了标记它。我们可以标记它现在:
$ git tag -a v0.9 558151a$ git log --oneline --decorate --graph* 594f90b (HEAD, tag: v1.0, master) reverted to old class name* 8d585ea Merge branch 'fix_readme'|\| * 3ac015d (fix_readme) fixed readme title* | 3cbb6aa fixed readme title differently|/* 558151a (tag: v0.9) Merge branch 'change_class'|\| * 3467b0a changed the class name* | b7ae93b added from ruby|/* 17f4acf first commit
当你从远程的分支获取,tags将指向的跟踪对象将会自动的下载。
$ git fetch origin --tagsremote: Counting objects: 1832, done.remote: Compressing objects: 100% (726/726), done.remote: Total 1519 (delta 1000), reused 1202 (delta 764)Receiving objects: 100% (1519/1519), 1.30 MiB | 1.21 MiB/s, done.Resolving deltas: 100% (1000/1000), completed with 182 local objects.From git://github.com:example-user/example-repo* [new tag] v1.0 -> v1.0* [new tag] v1.1 -> v1.1
如果你仅仅需要一个简单的标记,使用git fetch <remote> tag <tag-name>即可。
默认,push 到远程分支不会包括标签。可以在push时使用--tags参数包含标签
总而言之,你使用git tag 标记一个重要的提交或者点。比使用SHA更难以忘记。

原创粉丝点击