版本控制工具Git

用户设置

设置全局用户名与邮箱:html

$ git config --global user.name "Firstname Lastname"
$ git config --global user.email "your_email@your_email.com"

如需将一个文件夹归入git版本控制,能够cd进入该文件夹,并执行以下命令:git

$ git init

获取一个git库

注意:通过add操做和commit操做后的,均为已跟踪文件。github

1. 克隆远程git库到本地当前路径下的hello-world目录

$ git clone git://github.com/git/hello-world.git hello-world api

2. 使用命令 git add 开始跟踪一个新文件(暂存改动)

$ git add README

3. 删除

使用命令 git rm 从本地git库中删除文件,而且在当前工做目录中被一并删除:安全

$ git rm (files) 

$ git rm -r (directories)
把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然但愿保留在当前工做目录中:
$ git rm --cached readme.txt

4. 文件更名

要在 Git 中对文件更名,能够这么作:服务器

$ git mv file_from file_to

5. 查看修改

查看修改以后尚未暂存起来的变化内容,不加参数直接输入 git diff,以下:分布式

git diff

查看已经暂存起来的文件和上次提交时的快照之间的差别,能够用 git diff --cached命令:post

git diff --cached

6. 提交更改

提交更改到本地git库:fetch

$ git commit -m "xxx"

git commit 加上 -a 选项,Git 就会自动把全部已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤:ui

$ git commit -a –m "xxx"

7. 查看提交历史

$ git log

8. 修改最后一次提交

下面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

9. 取消操做

取消已经暂存的文件

git reset HEAD filename

取消对文件的修改(还未暂存的文件)

git checkout -- filename

10. 查看与添加远程库

查看当前远程库:

$ git remote -v

添加远程库:

git remote add 仓库名 远程仓库的地址

远程仓库的使用

1. 从远程仓库抓取数据

能够用下面的命令从远程仓库抓取数据到本地:

$ git fetch [remote-name]

此命令会到远程仓库中拉取全部你本地仓库中尚未的数据。运行完成后,你就能够在本地访问该远程仓库中的全部分支,将其中某个分支合并到本地,或者只是取出某个分支,一探究竟。

若是是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。因此,git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的全部更新(或是上次 fetch 以来别人提交的更新)。有一点很重要,须要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工做分支,只有当你确实准备好了,才能手工合并。

若是设置了某个分支用于跟踪某个远端仓库的分支,可使用 git pull 命令自动抓取数据下来,而后将远端分支自动合并到本地仓库中当前分支。在平常工做中咱们常常这么用,既快且好。实际上,默认状况下 git clone 命令本质上就是自动建立了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)。因此通常咱们运行 git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工做目录中的当前分支。

小结:git fetch只抓取数据,不会合并数据。git pull不只抓取数据,同时合并数据。

2. 推送数据到远程仓库

项目进行到一个阶段,要同别人分享目前的成果,能够将本地仓库中的数据推送到远程仓库。实现这个任务的命令很简单: git push [remote-name] [branch-name]。若是要把本地的 master 分支推送到origin 服务器上(再次说明下,克隆操做会自动使用默认的 master 和 origin 名字),能够运行下面的命令:

$ git push origin master  // 把本地的 master 分支推送到 服务器上origin

只有在所克隆的服务器上有写权限,或者同一时刻没有其余人在推数据,这条命令才会如期完成任务。若是在你推数据前,已经有其余人推送了若干更新,那你的推送操做就会被驳回。你必须先把他们的更新抓取到本地,合并到本身的项目中,而后才能够再次推送。

3. 查看远程仓库信息

咱们能够经过命令 git remote show [remote-name] 查看某个远程仓库的详细信息,好比要看所克隆的 origin 仓库,能够运行:

$ git remote show origin
* remote origin
  URL: git://github.com/schacon/ticgit.git
  Remote branch merged with 'git pull' while on branch master
    master
  Tracked remote branches
    master
    ticgit

除了对应的克隆地址外,它还给出了许多额外的信息。它友善地告诉你若是是在 master 分支,就能够用git pull 命令抓取数据合并到本地。另外还列出了全部处于跟踪状态中的远端分支。

上面的例子很是简单,而随着使用 Git 的深刻,git remote show 给出的信息可能会像这样:

$ git remote show origin
* remote origin
  URL: git@github.com:defunkt/github.git
  Remote branch merged with 'git pull' while on branch issues
    issues
  Remote branch merged with 'git pull' while on branch master
    master
  New remote branches (next fetch will store in remotes/origin)
    caching
  Stale tracking branches (use 'git remote prune')
    libwalker
    walker2
  Tracked remote branches
    acl
    apiv2
    dashboard2
    issues
    master
    postgres
  Local branch pushed with 'git push'
    master:master

它告诉咱们,运行 git push 时缺省推送的分支是什么(观察最后两行)。它还显示了有哪些远端分支尚未同步到本地(第7行的 caching 分支),哪些已同步到本地的远端分支在远端服务器上已被删除(译注:Stale tracking branches 下面的两个分支),以及运行 git pull 时将自动合并哪些分支(译注:前5行中列出的 issuesmaster 分支)。

4. 远程仓库的重命名

可使用 git remote rename 命令修改某个远程仓库在本地的简称,好比想把 pb 改为paul,能够这么运行:

$ git remote rename pb paul
$ git remote
origin
paul
注意,对远程仓库的重命名,也会使对应的分支名称发生变化,原来的 pb/master 分支如今成了 paul/master

碰到远端仓库服务器迁移,或者原来的克隆镜像再也不使用,又或者某个参与者再也不贡献代码,那么须要移除对应的远端仓库,能够运行 git remote rm 命令:

$ git remote rm paul
$ git remote
origin

分支与合并

1. fork一个远程仓库

1. 在目标GitHub项目页面上点击"Fork",来fork一个已有的repo到本身的github上。

2. clone远程仓库(1里fork到本身gitub上的远程仓库)到本地(若是是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下):

$ git clone git@github.com:username/Spoon-Knife.git

3. 添加远程端“upstream”,用于追踪上游仓储:

$ cd Spoon-Knife  
$ git remote add upstream git://github.com/octocat/Spoon-Knife.git

4. 获取来自上游仓储(远程端“upstream”)的更改:

$ git fetch upstream

   将上游(远程端“upstream”)的master分支合并到本地:

$ git merge upstream/master

注意:以上两步在合适的状况能够用 git pull [remoteName] [localBranchName] 命令合并:

$ git pull upstream

例如:git pull origin master 就是将origin这个版本库的代码更新到本地的master主支。

5. 提交全部更改到远程端“origin”的master分支(推送远程仓库:$ git push [remoteName] [localBranchName])

$ git push origin master

6. 若是想把本地的某个分支test提交到远程仓库,并做为远程仓库的master分支,或者做为另一个名叫test的分支,以下:

$git push origin test:master         // 提交本地test分支做为远程的master分支
$git push origin test:test           // 提交本地test分支做为远程的test分支

2. 使用分支(branch)进行工做

1. 查看分支

git branch

2. 建立一个新的分支

$ git branch 分支名

    切换分支进行工做

git checkout 分支名

注意:也能够直接建立一个新的分支并使用其工做:

git checkout -b 分支名

3. 删除分支

$ git branch -d [name]

-d选项只能删除已经参与了合并的分支,对于未有合并的分支是没法删除的。若是想强制删除一个分支,可使用-D选项

3. 对于代码贡献者更新本地工做分支,rebase or merge?

假设如今本地工做目录下有两个分支,一个是主分支master,另外一个是当前工做的主题分支mywork。

那么当你在主题分支mywork下工做时,想要导入来自上游库的更新时,使用git rebase

$ git rebase upstream/master mywork

或者直接(若是当前branch已是mywork):

$ git rebase upstream/master

注意,这将把当前branch的开发推动到一个新的起点,而不会引入多余的commits。rebase命令会把你的"mywork"分支里的每一个提交(commit)取消掉,而且把它们临时保存为补丁(patch)(这些补丁放到".git/rebase"目录中),而后把"mywork"分支更新 到最新的"origin"分支,最后把保存的这些补丁应用到"mywork"分支上。

咱们来看一下用合并(merge)和用rebase所产生的历史的区别:咱们将origin远程分支rebase或者merge到mywork分支

原图:

image

image

image

在rebase的过程当中,也许会出现冲突(conflict)。在这种状况,Git会中止rebase并会让你去解决冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index),而后,你无需执行 git-commit,只要执行:

$ git rebase --continue

在任什么时候候,你能够用--abort参数来终止rebase的行动,而且"mywork" 分支会回到rebase开始前的状态。

$ git rebase --abort

注意:当你在某个branch下工做时,git merge能够用来合并来自其余branch的更新。我的觉得如下这段话总结的很好:

若是merge的branch来自远程库,一次merge操做会增长一个额外的commit(“Merge branch 'master' of something”)。若是在一个须要发送Pull Request的主题branch下面进行这种操做,(我我的以为)这不是一种干净的手段。

当你在主线branch(例如master)下进行开发时,git merge能够用来吸取其余开发branch引入的新特性(包括主项目维护者用来直接merge Pull Requests),很恰当。

Pull Request发送以后

在在主题branch下完成须要的工做后,记得要push相应的主题branch到GitHub。

$ git push origin mywork  // 若是主题branch是mywork分支,那么把本地的mywork分支推送到origin服务器上

注意:若是远程仓库有mywork分支,则直接推送。若是没有mywork分支,则会在远程仓库建立mywork分支。

一旦你从本身的主题branch(例如mywork分支)推送了一条Pull Request,那么在这条Pull Request被关闭以前,再次向这个branch里push代码,全部的commits都会被自动追加到这个Pull Request后面(不须要再另开Pull Request)。

这个功能尤为有用,好比你最初提交的Pull Request里存在某些问题,项目维护者要求你打回去修改;或者要求你给你的新feature添加一条相应的unit test(这种状况简直太常见了)。只要追加commits到你的这个主题branch中便可。

Pull Request关闭以后

若是是已经被项目持有者merge后关闭的Pull Request,你能够在github页面的最下方找到一个“Delete this branch”的蓝色按钮。这代表这个主题branch的历史使命已经完成(mywork的commit已经被合并到主项目中),能够安全地从远程库中删除了。

在本地库中亦可删除这个branch:

$ git branch -d mywork

反之,若是你的主题branch并无被merge就被维护者关掉的话,你还能够继续再拿这个branch来开新的Pull Request去骚扰主项目。

小结

1. 如下状况下能够直接使用master branch来提交Pull Request:

你只想为主项目贡献某一处代码,贡献完本身的repo就能够扔的那种。

你打算为主项目长期贡献代码,并且但愿追随原项目的主线开发,不保留本身的特性。

你打算为主项目长期贡献代码,默认master branch追随原项目主线,把本身的特性放到别的branch中。

2. 若是想用master branch彻底来作本身的开发。在这种情形下,应该使用主题branch来提交Pull Request。

master branch会从上游库合并更新,可是这些merge自己的commits显然不可能做为返还到上游库的Pull Request的一部分。同时master branch存在本身的(未被merge或者不想被merge到上游库的)commits。

3. 鉴于Git的分布式开发哲学,每个库都可以看做是一个独立的项目,显然是后一种(为每个新特性创建一个专门的主题branch来向主项目推送Pull Request)的贡献方式更可取。

参考文献

1. http://git-scm.com/book

2. https://help.github.com/articles/fork-a-repo

3. http://gitbook.liuhui998.com/index.html

4. http://www.soimort.org/posts/149/

5. http://blog.csdn.net/ithomer/article/details/7529022

相关文章
相关标签/搜索