您的位置:首页 > 其它

版本控制工具Git

2014-09-18 01:28 357 查看

用户设置

设置全局用户名与邮箱:

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

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

$ git init

获取一个git库

注意:经过add操作和commit操作后的,均为已跟踪文件。

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

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

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命令:

git diff --cached

6. 提交更改

提交更改到本地git库:

$ git commit -m "xxx"

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

$ 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 分支推送到[code]origin
服务器上[/code]
只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,这条命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那你的推送操作就会被驳回。你必须先把他们的更新抓取到本地,合并到自己的项目中,然后才可以再次推送。

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行中列出的
issues
master
分支)。

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分支

原图:












在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: