Git 的使用
Ubuntu 下配置
Git 是一个快速、可扩展的分布式版本控制系统,它具有极为丰富的命令集,对内部系统提供了高级操作和完全访问。
一、Git安装:
1、 二进制方式安装:
$ sudo apt-get install git-core
安装完成后,在终端中输入 git 就可以看到相关的命令了。如果只是需要使用git来管理本地的代码,那么现在就可以
使用了。如果需要和github上的项目结合,还需要做其他的一些操作。
2、github帐号的申请
如果只是需要将github上感兴趣的代码拷贝到本地,自己进行修改使用,而不打算共享发布的话,其实不申请
帐号也没有关系,只需要 git clone 代码到本地就可以了。 $ git clone git:// IP work(工作目录名)。毕竟使用
github 就是为了开源的目的,首先去 github.com 上注册一个帐号。
3、在本地建立一个文件夹,然后做一些全局变量的初始化
$ git config --global user.name = "用户名或者用户ID"
$ git config --global user.email = 邮箱
[diego@localhost ~/data/20150812]# git config --global user.email "abc@abc.com"
[diego@localhost ~/data/20150812]# git config --global user.name abc"
[diego@localhost ~/data/20150812]# git config --list
user.name=abc
user.email=abc@abc.com
这两个选项会在以后的使用过程中自动添加到代码中。
4、创建验证用的公钥
这个是比较复杂和困扰大多数人的地方,因为 git 是通过 ssh 的方式访问资源库的,所以需要在本地创建验证
用的文件。使用命令:$ ssh-keygen -C 'you email address@gmail.com' -t rsa会在用户目录 ~/.ssh/ 下建立相应
的密钥文件.可以使用 $ ssh -v git@github.com 命令来测试链接是否畅通。
5、上传公钥
在 github.com 的界面中 选择右上角的 Account Settings,然后选择 SSH Public Keys ,选择新加。 Title 可
以随便命名,Key 的内容拷贝自 ~/.ssh/id_rsa.pub 中的内容,完成后,可以再使用 ssh -v git@github.com 进行
测试。看到下面的信息表示验证成功。
二、Git配置与使用
利用 github 来管理自己的项目,可以按照下面的步骤进行
1、建立仓库
在需要建立项目的文件夹中,使用 git init 进行仓库的建立。完成后,可以看到文件家中多了一个 .git 隐藏目录。
2、添加文件
使用 git add . 来进行初始文件的添加。这里 . 表示将文件夹下所有的文件都添加进去,我们也可以指定文件进
行添 加。
3、提交文件
使用 git commit -m 'comment' 提交,可以将编辑的内容进行提交。
4、删除或增加github远程来源
git remote add origin https://github.com/Git-Elite/CodeBase.git //蓝色部分为github托管的仓库地址
5、提交至github仓库
git push origin master
6 删除文件
先本地删除 rm student/libstudent.so
再git rm student/libstudent.so
7 本地和远端都有修改,
在本地执行git stash
然后git pull origin 0901 拉下远端code
然后git pop stash
8 执行git add后发现git diff 不起作用
git diff --cached
转 push本地代码到github出错
$ git push -u origin master
To git@github.com:******/Demo.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:******/Demo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
网上搜索了下,是因为远程repository和我本地的repository冲突导致的,而我在创建版本库后,在github的版本库页面点击了创建README.md文件的按钮创建了说明文档,但是却没有pull到本地。这样就产生了版本冲突的问题。
有如下几种解决方法:
1.使用强制push的方法:
$ git push -u origin master -f
这样会使远程修改丢失,一般是不可取的,尤其是多人协作开发的时候。
2.push前先将远程repository修改pull下来
$ git pull origin master
$ git push -u origin master
3.若不想merge远程和本地修改,可以先创建新的分支:
$ git branch [name]
然后push
$ git push -u origin [name]
http://www.ihref.com/read-16369.html
windows下配置参加这篇文章 https://github.com/JiapengLi/GitTutorial
git branch -a 查看所有分支以及当前分支
git checkout master 来切换branch
git remote -v 查看远端的git信息
[diego@localhost ~/work/branch_bug_fix/rtqa_center]# git remote -v
origin ssh://git@10.2.1.43:9922/1v1/rtqa_center.git (fetch)
origin ssh://git@10.2.1.43:9922/1v1/rtqa_center.git (push)
[diego@localhost ~/work/branch_bug_fix/rtqa_center]# git branch -a
bug-fix
* master
remotes/origin/HEAD -> origin/master
remotes/origin/bug-fix
remotes/origin/dev
remotes/origin/master
[diego@localhost ~/work/branch_bug_fix/rtqa_center]# git checkout bug-fix
Switched to branch 'bug-fix'
[diego@localhost ~/work/branch_bug_fix/rtqa_center]# git branch -a
* bug-fix
master
remotes/origin/HEAD -> origin/master
remotes/origin/bug-fix
remotes/origin/dev
remotes/origin/master
[diego@localhost ~/work/branch_bug_fix/rtqa_center]#
Git 中的tag指向一次commit的id,通常用来给开发分支做一个标记,如标记一个版本号。
打标签
git tag -a v1.01 -m "Relase version 1.01"
注解:git tag 是打标签的命令,-a 是添加标签,其后要跟新标签号,-m 及后面的字符串是对该标签的注释。
提交标签到远程仓库
git push origin --tags
注解:就像git push origin master 把本地修改提交到远程仓库一样,-tags可以把本地的打的标签全部提交到远程仓库。
删除标签
git tag -d v1.01
注解:-d 表示删除,后面跟要删除的tag名字
删除远程标签
git push origin :refs/tags/v1.01
注解:就像git push origin :branch_1 可以删除远程仓库的分支branch_1一样, 冒号前为空表示删除远程仓库的tag。
查看标签
git tag
或者
git tag -l
新建分支
git checkout -b dispatch201511
然后手动修改一个文件
git commit -a -m "new a branch\"
git push origin dispatch201511
大功告成
3.2 Git 分支 - 分支的新建与合并
分支的新建与合并
让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流。 你将经历如下步骤:
-
开发某个网站。
-
为实现某个新的需求,创建一个分支。
-
在这个分支上开展工作。
正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。 你将按照如下方式来处理:
-
切换到你的线上分支(production branch)。
-
为这个紧急任务新建一个分支,并在其中修复它。
-
在测试通过之后,切换回线上分支,然后合并这个修补分支,最后将改动推送到线上分支。
-
切换回你最初工作的分支上,继续工作。
新建分支
Figure 3-10. 一个简单提交历史现在,你已经决定要解决你的公司使用的问题追踪系统中的 #53 问题。 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b
参数的 git checkout
命令:
$
git checkout -b iss53Switched to a new branch "iss53"
它是下面两条命令的简写:
Figure 3-11. 创建一个新分支指针$
git branch iss53$
git checkout iss53
你继续在 #53 问题上工作,并且做了一些提交。 在此过程中,iss53
分支在不断的向前推进,因为你已经检出到该分支(也就是说,你的 HEAD
指针指向了 iss53
分支)
Figure 3-12. iss53 分支随着工作的进展向前推进$
vim index.html$
git commit -a -m'added a new footer [issue 53]'
现在你接到那个电话,有个紧急问题等待你来解决。 有了 Git 的帮助,你不必把这个紧急问题和iss53
的修改混在一起,你也不需要花大力气来还原关于 53# 问题的修改,然后再添加关于这个紧急问题的修改,最后将这个修改提交到线上分支。 你所要做的仅仅是切换回 master
分支。
但是,在你这么做之前,要留意你的工作目录和暂存区里那些还没有被提交的修改,它可能会和你即将检出的分支产生冲突从而阻止 Git 切换到该分支。 最好的方法是,在你切换分支之前,保持好一个干净的状态。 有一些方法可以绕过这个问题(即,保存进度(stashing) 和 修补提交(commit amending)),我们会在 储藏与清理 中看到关于这两个命令的介绍。 现在,我们假设你已经把你的修改全部提交了,这时你可以切换回 master
分支了:
$
git checkout masterSwitched to branch 'master'
这个时候,你的工作目录和你在开始 #53 问题之前一模一样,现在你可以专心修复紧急问题了。 请牢记:当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样。
接下来,你要修复这个紧急问题。 让我们建立一个针对该紧急问题的分支(hotfix branch),在该分支上工作直到问题解决:
Figure 3-13. 基于$
git checkout -b hotfixSwitched to a new branch 'hotfix'
$
vim index.html$
git commit -a -m'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)
master
分支的紧急问题分支 hotfix branch
你可以运行你的测试,确保你的修改是正确的,然后将其合并回你的 master
分支来部署到线上。 你可以使用 git merge
命令来达到上述目的:
$
git checkout master$
git merge hotfixUpdating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
在合并的时候,你应该注意到了"快进(fast-forward)"这个词。 由于当前 master
分支所指向的提交是你当前提交(有关 hotfix 的提交)的直接上游,所以 Git 只是简单的将指针向前移动。 换句话说,当你试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。
现在,最新的修改已经在 master
分支所指向的提交快照中,你可以着手发布该修复了。
master
被快进到 hotfix
关于这个紧急问题的解决方案发布之后,你准备回到被打断之前时的工作中。 然而,你应该先删除hotfix
分支,因为你已经不再需要它了 —— master
分支已经指向了同一个位置。 你可以使用带 -d
选项的 git branch
命令来删除分支:
$
git branch -d hotfixDeleted branch hotfix (3a0874c).
现在你可以切换回你正在工作的分支继续你的工作,也就是针对 #53 问题的那个分支(iss53 分支)。
Figure 3-15. 继续在$
git checkout iss53Switched to branch "iss53"
$
vim index.html$
git commit -a -m'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
iss53
分支上的工作
你在 hotfix
分支上所做的工作并没有包含到 iss53
分支中。 如果你需要拉取 hotfix
所做的修改,你可以使用 git merge master
命令将 master
分支合并入 iss53
分支,或者你也可以等到iss53
分支完成其使命,再将其合并回 master
分支。
分支的合并
假设你已经修正了 #53 问题,并且打算将你的工作合并入 master
分支。 为此,你需要合并 iss53
分支到 master
分支,这和之前你合并 hotfix
分支所做的工作差不多。 你只需要检出到你想合并入的分支,然后运行 git merge
命令:
$
git checkout masterSwitched to branch 'master'
$
git merge iss53Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
这和你之前合并 hotfix
分支的时候看起来有一点不一样。 在这种情况下,你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master
分支所在提交并不是 iss53
分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4
和 C5
)以及这两个分支的工作祖先(C2
),做一个简单的三方合并。
和之间将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。
Figure 3-17. 一个合并提交需要指出的是,Git 会自行决定选取哪一个提交作为最优的共同祖先,并以此作为合并的基础;这和更加古老的 CVS 系统或者 Subversion (1.5 版本之前)不同,在这些古老的版本管理系统中,用户需要自己选择最佳的合并基础。 Git 的这个优势使其在合并操作上比其他系统要简单很多。
既然你的修改已经合并进来了,你已经不再需要 iss53
分支了。 现在你可以在任务追踪系统中关闭此项任务,并删除这个分支。
$
git branch -d iss53
遇到冲突时的分支合并
有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 如果你对 #53 问题的修改和有关 hotfix
的修改都涉及到同一个文件的同一处,在合并它们的时候就会产生合并冲突:
$
git merge iss53Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂停下来,等待你去解决合并产生的冲突。 你可以在合并冲突后的任意时刻使用 git status
命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件:
$
git statusOn branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来。 Git 会在有冲突的文件中加入标准的冲突解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。 出现冲突的文件会包含一些特殊区段,看起来像下面这个样子:
<<<<<<
< HEAD:index.html
<
div
id=
"footer"
>
contact : email.support@github.com</div>
=======<div
id=
"footer"
>
please contact us at support@github.com</div>
>>>>>>> iss53:index.html
这表示 HEAD
所指示的版本(也就是你的 master
分支所在的位置,因为你在运行 merge 命令的时候已经检出到了这个分支)在这个区段的上半部分(=======
的上半部分),而 iss53
分支所指示的版本在 =======
的下半部分。 为了解决冲突,你必须选择使用由 =======
分割的两部分中的一个,或者你也可以自行合并这些内容。 例如,你可以通过把这段内容换成下面的样子来解决冲突:
<div
id=
"footer"
>
please contact us at email.support@github.com</div>
上述的冲突解决方案仅保留了其中一个分支的修改,并且 <<<<<<<
, =======
, 和 >>>>>>>
这些行被完全删除了。 在你解决了所有文件里的冲突之后,对每个文件使用 git add
命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决。
如果你想使用图形化工具来解决冲突,你可以运行 git mergetool
,该命令会为你启动一个合适的可视化合并工具,并带领你一步一步解决这些冲突:
$
git mergetoolThis message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
如果你想使用除默认工具(在这里 Git 使用 opendiff
做为默认的合并工具,因为作者在 Mac 上运行该程序)外的其他合并工具,你可以在 “下列工具中(one of the following tools)” 这句后面看到所有支持的合并工具。 然后输入你喜欢的工具名字就可以了。
NOTE
如果你需要更加高级的工具来解决复杂的合并冲突,我们会在 高级合并 介绍更多关于分支合并的内容。
等你退出合并工具之后,Git 会询问刚才的合并是否成功。 如果你回答是,Git 会暂存那些文件以表明冲突已解决: 你可以再次运行 git status
来确认所有的合并冲突都已被解决:
$
git statusOn branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
如果你对结果感到满意,并且确定之前有冲突的的文件都已经暂存了,这时你可以输入 git commit
来完成合并提交。 默认情况下提交信息看起来像下面这个样子:
Merge branch 'iss53'
Conflicts:
index.html
#
#
It looks like you may be committing a merge.#
If this is not correct, please remove the file#
.git/MERGE_HEAD#
and try again.#
Please enter the commit messagefor
your changes. Lines starting#
with'#'
will be ignored, and an empty message aborts the commit.#
On branch master#
All conflicts fixed but you are still merging.#
#
Changes to be committed:#
modified: index.html#
如果你觉得上述的信息不够充分,不能完全体现分支合并的过程,你可以修改上述信息,添加一些细节给未来检视这个合并的读者一些帮助,告诉他们你是如何解决合并冲突的,以及理由是什么。
这个定义或许会有意想不到的影响。比如,假设你有两个分支,“stable” 和 “new-idea”, 它们的顶端在版本 E 和 F:
A-----C----E ("stable") \ B-----D-----F ("new-idea")
所以提交(commits) A, C和 E 属于“stable”,而 A, B, D 和 F 属于 “new-idea”。如果之后你用下面的命令 将“new-idea” merge 到 “stable” :
git checkout stable # Change to work on the branch "stable" git merge new-idea # Merge in "new-idea"
…那么你会得到这个:
A-----C----E----G ("stable") \ / B-----D-----F ("new-idea")
要是你继续在“new idea” 和“stable”分支提交, 会得到:
A-----C----E----G---H ("stable") \ / B-----D-----F----I ("new-idea")
因此现在A, B, C, D, E, F, G 和 H 属于 “stable”,而A, B, D, F 和 I 属于 “new-idea”。
当然了,分支确实有些特殊的属性——其中最重要的是,如果你在一个分支进行作业并创建了一个新的提交(commits),该分支的顶端将前进到那个提交(commits)。这正是你所希望的。当用git merge 进行合并(merge)的时候,你只是指定了要合并到当前分支的那个并入分支,以及当前分支的当前进展。
old mode 100755 new mode 100644让git忽略掉文件权限检查:git config --add core.filemode false
抄自:http://hi.baidu.com/lzhsdly/blog/item/9b9abc6c4d7e56e64216947d.html