git &github 快捷入门

本节内容

  1. github介绍
  2. 安装
  3. 仓库创制& 提交代码
  4. 代码回滚
  5. 工作区和暂存区
  6. 注销修改
  7. 剔除操作
  8. 长途仓库
  9. 分层管理
  10. 多个人合营
  11. github使用
  12. 忽视特殊文件.gitignore

 

 

1.github介绍

多三个人都领悟,Linus在1992年开创了开源的Linux,从此,Linux系统不断向上,已经济体改成最大的服务器系统软件了。

Linus即使创制了Linux,但Linux的恢弘是靠全世界热心的志愿者到场的,这么多少人在世界外地为Linux编写代码,那Linux的代码是怎么着管理的吧?

事实是,在二零零三年从前,世界内地的志愿者把源代码文件通过diff的主意发给Linus,然后由Linus自己通过手工业方式合并代码!

您大概会想,为何Linus不把Linux代码放到版本控制系统里吧?不是有CVS、SVN那一个免费的版本控制系统啊?因为Linus坚定地反对CVS和SVN,那一个集中式的版本控制系统不仅速度慢,而且必须联网才能利用。有局地商用的版本控制系统,就算比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。

然而,到了2000年,Linux系统已经提高了十年了,代码库之大让Linus很难继续透过手工业格局管理了,社区的弟兄们也对那种办法表达了强烈不满,于是Linus选拔了多少个买卖的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这么些版本控制系统。

安乐的大好局面在二〇〇七年就被打破了,原因是Linux社区牛人聚集,不免沾染了有个别梁山民族豪杰的江湖习惯。开发萨姆ba的Andrew试图破解BitKeeper的协议(这么干的实际也不只她贰个),被BitMover公司发现了(监察和控制工作做得没错!),于是BitMover公司怒了,要撤回Linux社区的免费使用权。

Linus能够向BitMover公司道个歉,保险从此严俊保险弟兄们,嗯,那是不容许的。真实景况是这么的:

Linus花了两周时间自身用C写了二个分布式版本控制系统,那就是Git!半年以内,Linux系统的源码已经由Git管理了!牛是怎么定义的啊?大家能够体会一下。

Git飞快成为最流行的分布式版本控制系统,越发是二〇〇九年,GitHub网站上线了(github是2个基于git的代码托管平台,付成本户能够建私人仓库,大家一般的免成本户只可以动用集体仓库,也便是代码要当面。),它为开源项目免费提供Git存款和储蓄,无数开源项目起先搬迁至GitHub,包涵jQuery,PHP,Ruby等等。

野史便是这么偶然,倘使不是当时BitMover公司威迫Linux社区,恐怕今后大家就没有免费而超级好用的Git了。

 

今天,GitHub已是:

  • 三个负有143万开发者的社区。其中不乏Linux发明者Torvalds那样的头等黑客,以及Rails创办者DHH如此的年轻极客。
  • 其一星球上最流行的开源托管服务。如今已托管431万git项目,不仅进一步多出名开源项目迁入GitHub,比如Ruby
    on
    Rails、jQuery、Ruby、Erlang/OTP;近三年流行的开源库往往在GitHub先发,例如:BootStrapNode.jsCoffeScript等。
  • alexa全世界排行414的网站。

 

2. git安装

安装Git

最早Git是在Linux上支付的,十分长一段时间内,Git也不得不在Linux和Unix系统上跑。然而,渐渐地有人把它移植到了Windows上。现在,Git能够在Linux、Unix、Mac和Windows这几大平台上不奇怪运营了。

 

 

 

 

 

 

要利用Git,第②步当然是安装Git了。依据你近年来选择的平台来读书下边包车型大巴文字:

在Linux上安装Git

率先,你能够试着输入git,看看系统有没有安装Git:

1
2
3
$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

像上面的指令,有诸多Linux会友好地报告您Git没有安装,还会告诉你什么设置Git。

一旦您碰巧用Debian或Ubuntu
Linux,通过一条sudo apt-get install git就足以直接完结Git的安装,卓殊简单。

 

3.版本库创立

哪些是版本库呢?版本库又名仓库,英文名repository,你能够大约明了成二个索引,这么些目录里面包车型地铁享有文件都得以被Git管理起来,每种文件的改动、删除,Git都能跟踪,以便任何时刻都可以追踪历史,大概在今后有些时刻能够“还原”。

故此,创设1个版本库非凡简单,首先,选取三个老少咸宜的地点,成立二个空目录:

1
2
3
4
5
mkdir git_trainning
cd git_trainning/
 
$ git init
Initialized empty Git repository in /Users/alex/git_trainning/.git/

转眼间Git就把库房屋修建好了,而且告诉你是多个空的库房(empty Git
repository),细心的读者能够窥见当前目录下多了一个.git的目录,这些目录是Git来跟踪管理版本库的,没事千万不要手动修改那么些目录里面包车型客车公文,不然改乱了,就把Git仓库给毁掉了。

一经你从未见到.git目录,那是因为这几个目录私下认可是隐藏的,用ls -ah指令就足以望见。

把文件添加到版本库

先是这里再明显一下,全部的版本控制系统,其实只好跟踪文本文件的变更,比如TXT文件,网页,全数的程序代码等等,Git也不例外。版本控制系统能够告知您每一趟的变动,比如在第4行加了一个单词“Linux”,在第九行删了三个单词“Windows”。而图片、录制那一个二进制文件,固然也能由版本控制系统一管理理,但有心无力跟踪文件的更动,只好把二进制文件每便变更串起来,也正是只略知一二图片从100KB改成了120KB,但到底改了啥,版本控制系统不清楚,也没法精通。

噩运的是,Microsoft的Word格式是二进制格式,由此,版本控制系统是迫不得已跟踪Word文件的更动的,前面大家举的例证只是为了演示,即使要实在使用版本控制系统,就要以纯文本格局编写文件。

因为文件是有编码的,比如汉语有常用的GBK编码,日文有Shift_JIS编码,如若没有历史遗留难点,强烈提出使用正式的UTF-8编码,全部语言使用同一种编码,既没有争持,又被全体平台所支持。

言归正传,将来我们编辑三个first_git_file.txt文件,内容如下:

1
2
3
4
$ vim first_git_file.txt
 
first time using git, excited!
第一次用git哈哈

自然要放权git_trainning目录下(子目录也行),因为那是3个Git仓库,放到任哪个地点方Git再厉害也找不到这几个文件。

和把大象放到三门双门电冰箱必要3步比较,把三个文件放到Git仓库只需求两步。

第一步,用命令git add告诉Git,把文件添加到仓库:

1
$ git add first_git_file.txt

履行上边包车型地铁通令,没有任何展现,表明添加成功。

第二步,用命令git commit报告Git,把文件提交到仓库:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ git commit -m "commit my first git file"
 
[master (root-commit) 621e6e4] commit my first git file
 Committer: Alex Li <alex@alexs-macbook-pro.local>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:
 
    git config --global --edit
 
After doing this, you may fix the identity used for this commit with:
 
    git commit --amend --reset-author
 
 file changed, 2 insertions(+)
 create mode 100644 first_git_file.txt
</alex@alexs-macbook-pro.local>

个中浅绛红部分的意思是,你在往git库里提交代码时,你要求告诉git你是何人,那样git就会纪录下来是什么人改的代码,其实正是为着以往查询方便,你只供给提供一个名字和邮件地址就足以,那里本身的git直接通过主机名本人创办了三个,但您能够由此git
config –global –edit
修改

 

差不离解释一下git commit命令,-m前边输入的是这次交付的证实,能够输入任意内容,当然最棒是有意义的,那样您就能从历史记录里方便地找到改动记录。

嫌麻烦不想输入-m "xxx"行依旧不行?确实有点子能够这么干,可是鲜明不提出你如此干,因为输入表明对自身对人家阅读都很关键。

缘何Git添Gavin件必要addcommit总结两步呢?因为commit能够3遍提交很多文书,所以你能够频仍add不相同的文书,比如:

1
2
3
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

  

4. 代码回滚

4.1代码修改并付出  

作者们早已成功地加上并提交了3个first_git_file.txt文件,以往,是时候继续做事了,于是,大家继承修改first_git_file.txt文件,改成如下内容:

1
2
3
First time using git, excited! update ...
insert line here...
第一次用git哈哈

现在,运行git status一声令下看看结果:

1
2
3
4
5
6
7
8
9
$ git status
On branch master
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:   first_git_file.txt
 
no changes added to commit (use "git add" and/or "git commit -a")

就算Git告诉大家first_git_file.txt被涂改了,但借使能看看具体修改了怎样内容,自然是很好的。比如你休假两周从外国归来,第②天上班时,已经记不清上次怎么修改的readme.txt,所以,要求用git diff以此命令看看:  

1
2
3
4
5
6
7
8
9
10
11
$ git diff first_git_file.txt
diff --git a/first_git_file.txt b/first_git_file.txt
index 2d13c2c..248d853 100644
--- a/first_git_file.txt
+++ b/first_git_file.txt
@@ -1,3 +1,4 @@
-first time using git, excited!
+First time using git, excited! update ...
 insert line here...
 第一次用git哈哈
+insert line again haha...

出口中+号深紫展现的正是修改或新增的内容,-号清水蓝突显的就是去掉或被改动的剧情

通晓了对first_git_file.txt 作了怎么修改后,再把它交给到库房就放心多了,提交修改和付出新文件是同一的两步,第1步是git add

1
2
3
4
5
$ git add . # .  代表把当前目录下所有改动的文件都提交到代码库
Alexs-MacBook-Pro:git_trainning alex$ git commit -m "commit changes"
[master 50ad6b5] commit changes
 Committer: Alex Li <alex@Alexs-MacBook-Pro.local>
 file changed, 1 insertion(+)

付给后,大家再用git status指令看看仓库的如今气象:  

1
2
3
$ git status
# On branch master
nothing to commit (working directory clean)

Git告诉大家脚下从未索要交给的改动,而且,工作目录是根本(working
directory clean)的。

  

4.2 代码回滚  

现行反革命,你已经学会了修改文件,然后把修改提交到Git版本库,今后,再演习二次,修改first_git_file.txtt文件如下: 

1
2
3
4
5
First time using git, excited! update ...
insert line here..改之前的.
第一次用git哈哈
insert line again haha...
加点新内容 

接下来尝试提交:

1
2
3
4
5
$ git add first_git_file.txt
$ git commit -m "add new content"
[master 4459657] add new content
 Committer: Alex Li <alex@Alexs-MacBook-Pro.local>
 file changed, 2 insertions(+), 1 deletion(-)

像那样,你不停对文本举办改动,然后不断提交修改到版本库里,就好比玩LANDPG游戏时,每经过一关就会活动把嬉戏状态存盘,假若某一关没过去,你仍是能够选用读取前一关的图景。有个别时候,在打Boss以前,你会手动存盘,以便万一打Boss战败了,能够从近期的地点重新初步。Git也是均等,每当你认为文件修改到自然水平的时候,就足以“保存2个快速照相”,那些快速照相在Git中被称为commit。一旦你把公文字改正乱了,或然误删了文本,还足以从近期的贰个commit过来,然后继续做事,而不是把多少个月的工作成果全体不见。

前日,我们回看一下first_git_file.txt文件一共有多少个本子被交给到Git仓Curry了: 

版本1

1
2
first time using git, excited!
第一次用git哈哈

版本2

1
2
3
first time using git, excited!
insert line here...
第一次用git哈哈

版本3

1
2
3
4
first time using git, excited!
insert line here...
第一次用git哈哈
insert line again haha...

版本4

1
2
3
4
5
First time using git, excited! update ...
insert line here..改之前的.
第一次用git哈哈
insert line again haha...
加点新内容

自然了,在骨子里工作中,大家脑子里怎么或然记得三个几千行的公文每便都改了怎么着内容,不然要版本控制系统为何。版本控制系统肯定有有个别命令能够告知大家历史记录,在Git中,大家用git log指令查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ git log
commit 445965781d1fd0d91e76d120450dd18fd06c7489
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 18:44:29 2016 +0800
 
    add new content
 
commit be02137bb2f54bbef0c2e99202281b3966251952
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 17:55:16 2016 +0800
 
    update again
 
commit 50ad6b526810bb7ccfea430663757ba2337b9816
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 17:46:51 2016 +0800
 
    commit changes
 
commit 621e6e44d04fa6a1cdc37826f01efa61b451abd1
Author: Alex Li <alex@Alexs-MacBook-Pro.local>
Date:   Tue Oct 4 17:42:50 2016 +0800
 
    commit my first git file

git log指令展现从眼前到最远的交给日志,大家能够见见四次提交,近期的一回是add
new content,上3遍是update
again,最早的叁回是commit my first git file
若是嫌输出新闻太多,看得一无可取的,能够试试加上--pretty=oneline参数:  

1
2
3
4
5
$ git log --pretty=oneline
445965781d1fd0d91e76d120450dd18fd06c7489 add new content
be02137bb2f54bbef0c2e99202281b3966251952 update again
50ad6b526810bb7ccfea430663757ba2337b9816 commit changes
621e6e44d04fa6a1cdc37826f01efa61b451abd1 commit my first git file

须求友情提醒的是,你看到的一大串类似3628164...882e1e0的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是1个SHA1总计出来的二个十分大的数字,用十六进制表示,而且你看看的commit id和本人的大势所趋不平等,以你自身的为准。为啥commit id须求用这么一大串数字代表呢?因为Git是分布式的版本控制系统,后边大家还要探究多个人在同二个版本Curry干活,假若我们都用1,2,3……作为版本号,那一定就抵触了。  

 

回滚回滚回滚  

好了,现在大家运营时光穿梭机,准备把first_git_file.txt回退到上2个本子,也正是“update
again”的格外版本,如何是好呢?

先是,Git必须懂妥当前版本是哪个版本,在Git中,用HEAD代表近日版本,也等于时尚的交付be02137bb2f54bbef0c2e99202281b396625一九五一(注意本身的交给ID和您的必定分化),上3个版本正是HEAD^,上上二个本子正是HEAD^^,当然往上98个版本写玖拾陆个^相比较便于数但是来,所以写成HEAD~100

今昔,我们要把当下版本“add new content”回退到上多少个版本“update
again”,就足以采纳git reset命令:

1
2
$ git reset --hard HEAD^
HEAD is now at be02137 update again

此刻再看您的文书内容,果然就退回去了

1
2
3
4
5
more first_git_file.txt
First time using git, excited! update ...
insert line here...
第一次用git哈哈
insert line again haha...

那时还是能连续再往前回退四个本子,不过且慢,然大家用git log再看看现在版本库的事态:

1
2
3
4
$ git log --pretty=oneline
be02137bb2f54bbef0c2e99202281b3966251952 update again
50ad6b526810bb7ccfea430663757ba2337b9816 commit changes
621e6e44d04fa6a1cdc37826f01efa61b451abd1 commit my first git file

最新的充裕版本add new
content已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回来已经回不去了,咋做?

方法其实仍然某个,只要上边的命令行窗口还未曾被关掉,你就可以本着往上找啊找啊,找到十三分add
new content的commit id是445965781d1fd0d91e76d120450dd18fd06c7489

,于是就足以内定回到未来的有个别版本:

1
2
git reset --hard 4459657
HEAD is now at 4459657 add new content

版本号没供给写全,前贰个人就能够了,Git会自动去找。当然也不可能只写前一两位,因为Git只怕会找到三个版本号,就无法明确是哪三个了。

再如履薄冰地看望first_git_file.txt的内容:

1
2
3
4
5
First time using git, excited! update ...
insert line here..改之前的.
第一次用git哈哈
insert line again haha...
加点新内容

果不其然,小编胡汉三又重临了。

Git的版本回退速度相当的慢,因为Git在里边有个针对当前版本的HEAD指南针,当您回退版本的时候,Git仅仅是把HEAD从指向add new content

 

今后,你回退到了有些版本,关掉了电脑,第②天深夜就后悔了,想重操旧业到新本子如何做?找不到新本子的commit
id如何做?

在Git中,总是有忏悔药能够吃的。当你用$ git reset –hard
HEAD^回退到update again版本时,再想过来到最新add new
content的本子,就务须找到add new contentL的commit
id。Git提供了一个指令git reflog用来记录您的每二回命令:

1
2
3
4
5
6
7
8
9
10
11
$ git reflog
4459657 HEAD@{0}: reset: moving to 4459657
be02137 HEAD@{1}: reset: moving to HEAD^
4459657 HEAD@{2}: commit: add new content
be02137 HEAD@{3}: reset: moving to be02137bb
50ad6b5 HEAD@{4}: reset: moving to 50ad6b5
621e6e4 HEAD@{5}: reset: moving to 621e6e44
50ad6b5 HEAD@{6}: reset: moving to HEAD^
be02137 HEAD@{7}: commit: update again
50ad6b5 HEAD@{8}: commit: commit changes
621e6e4 HEAD@{9}: commit (initial): commit my first git file

到头来舒了口气,第二行彰显add new content的commit
id是4459657,今后,你又能够乘坐时光机回到今后了。  

 

 

5. 工作区和暂存区

Git和其他版本控制系统如SVN的一个分化之处正是有暂存区的定义。

先来看名词解释。

工作区(Working Directory

固然您在处理器里能看到的目录,比如小编的git_trainning文件夹便是叁个工作区:

1
2
ls git_trainning/
first_git_file.txt

版本库(Repository)

工作区有1个隐形目录.git,那些不算工作区,而是Git的版本库。

Git的版本Curry存了诸多事物,个中最要害的就是称呼stage(恐怕叫index)的暂存区,还有Git为大家机关成立的第③个分支master,以及针对master的三个指针叫HEAD

图片 1

分支和HEAD的概念我们现在再讲。

前边讲了我们把文件往Git版本Curry丰硕的时候,是分两步执行的:

先是步是用git add把公文添加进去,实际上正是把文件修改添加到暂存区;

第2步是用git commit交给更改,实际上便是把暂存区的具有情节交给到当下支行。

因为我们创立Git版本库时,Git自动为大家创造了唯一二个master分支,所以,现在,git commit就是往master支行上提交更改。

您能够简简单单通晓为,需求提交的文件修改通通放到暂存区,然后,一遍性交给暂存区的全数修改。

俗话说,实践出真知。未来,大家再练习三次,先对first_git_file.txt做个修改,比如加上一行内容:

1
2
3
4
5
6
First time using git, excited! update ...
insert line here..改之前的.
第一次用git哈哈
insert line again haha...
加点新内容
update v5

下一场,在工作区新增四个readme.md文件文件(内容随便写)。

先用git status翻开一下意况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git status
On branch master
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:   first_git_file.txt
 
Untracked files:
  (use "git add <file>..." to include in what will be committed)
 
    readme.md
 
no changes added to commit (use "git add" and/or "git commit -a")

Git万分领会地告知大家,first_git_file.txt被修改了,而readme.md还常有没有被添加过,所以它的情事是Untracked

近来,使用命令git add .,再用git status再查看一下:

1
2
3
4
5
6
7
8
9
$ git add .
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    modified:   first_git_file.txt
    new file:   readme.md
</file>

近期,暂存区的情景就改成这样了:

图片 2

(盗图关系, 那里readme.txt = first_git_file.txt , LICENSE =
readme.md)

所以,git add命令实际上正是把要交给的持有修改放到暂存区(Stage),然后,执行git commit就能够3次性把暂存区的装有修改提交到支行。

1
2
3
4
$ git commit -m "知道暂存区stage的意思了"
[master 9d65cb2] 知道暂存区stage的意思了
 2 files changed, 2 insertions(+)
 create mode 100644 readme.md

借使付出后,假诺你又从未对工作区做其余改动,那么工作区正是“干净”的:

1
2
3
$ git status
On branch master
nothing to commit, working directory clean

于今版本库变成了如此,暂存区就不曾其他内容了:

图片 3

(盗图关系, 那里readme.txt = first_git_file.txt , LICENSE =
readme.md)

* *暂存区是Git非凡重要的定义,弄精晓了暂存区,就弄领悟了Git的不在少数操作到底干了怎样。

 

  

6. 收回修改  

本来,你是不会犯错的。可是今后是凌晨两点,你正在赶一份工作报告,你在readme.md中添加了一条龙:

1
2
3
#git study repo
git is great
but my stupid boss still prefers SVN.

在您准备付出前,一杯咖啡起了效益,你突然发现了“stupid
boss”大概会让您丢掉那些月的奖金!

既是错误发现得很及时,就可以很不难地校勘它。你能够删掉最终一行,手动把文件复苏到上1个版本的动静。假若用git status查阅一下:

1
2
3
4
5
6
7
8
9
10
git status
On branch master
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:   readme.md
 
no changes added to commit (use "git add" and/or "git commit -a")
</file></file>

你能够窥见,Git会告诉您,git checkout -- file能够抛弃工作区的改动:  

1
2
3
4
$ git checkout -- readme.md
 
more readme.md
#git study repo

您刚才添加的2行骂CEO的话就被撤废了,

命令git checkout -- readme.md情趣正是,把readme.md文本在工作区的修改总体裁撤,那里有三种状态:

一种是readme.md自修改后还一贯不被平放暂存区,今后,打消修改就回去和版本库一模一样的情状;

一种是readme.md早就添加到暂存区后,又作了修改,未来,撤除修改就回去添加到暂存区后的意况。

总的说来,正是让这些文件回到近期3次git commitgit add时的动静。

git checkout -- file指令中的--很重要,没有--,就改成了“切换来另一个支行”的命令,我们在后头的分段管理中会再一次相见git checkout命令。  

 

明天只若是黎明先生3点,你不但写了有的谬论,还git add到暂存区了:

1
2
3
4
5
6
7
8
cat readme.md
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
My stupid boss still prefers SVN.
 
$ git add readme.md

   

幸甚的是,在commit从前,你发觉了那几个题材。用git status查阅一下,修改只是丰裕到了暂存区,还并未交给: 

1
2
3
4
5
6
7
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    modified:   readme.md
</file>

Git同样告诉大家,用命令git reset HEAD file能够把暂存区的修改裁撤掉(unstage),重新放回工作区:

1
2
3
$ git reset HEAD readme.md
Unstaged changes after reset:
M   readme.md

git reset一声令下既能够回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的本子。

再用git status翻看一下,现在暂存区是根本的,工作区有修改

1
2
3
4
5
6
7
8
9
$ git status
# On branch master
# 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:   readme.md
#
no changes added to commit (use "git add" and/or "git commit -a")

还记得怎样扬弃工作区的修改吗?

1
2
3
4
$ git checkout -- readme.md
 
more readme.md
#git study repo

一体世界到底冷静了!

  

7. 刨除操作

在Git中,删除也是三个改动操作,大家实战一下,先添加2个新文件test.txt到Git并且付诸:  

1
2
3
4
5
$ git add .
$ git commit -m "add test.txt"
[master a8fa95a] add test.txt
 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test.txt

貌似情况下,你平常直接在文件管理器中把没用的文本删了,恐怕用rm指令删了

1
rm test.txt

以此时候,Git知道你剔除了文本,由此,工作区和版本库就不均等了,git status命令会立时告知你什么文件被去除了:

1
2
3
4
5
6
7
8
9
$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
 
    deleted:    test.txt
 
no changes added to commit (use "git add" and/or "git commit -a")

最近您有多少个采用,一是确实要从版本库中去除该文件,那就用命令git rm删掉,并且git commit

1
2
3
4
5
6
7
x$ git rm test.txt
rm 'test.txt'
 
$ git commit -m "remove test"
[master 03df00a] remove test
 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 test.txt

近日,文件就从版本库中被剔除了。

另一种状态是删错了,因为版本Curry还有啊,所以能够很自在地把误删的文本苏醒到新型版本:

1
$ git checkout -- test.txt

git checkout实则是用版本Curry的本子替换工作区的版本,无论工作区是修改依旧去除,都能够“一键还原”。  

 

  

  

8. 长途仓库  

到近年来结束,大家已经控制了怎样在Git仓库里对3个文件举行时光不断,你再也不用担心文件备份或然丢失的难题了。

但是有用过集中式版本控制系统SVN的童鞋会站出来说,那么些作用在SVN里早就有了,没见到Git有哪些尤其的地方。

毋庸置疑,假使只是在三个库房里管理文件历史,Git和SVN真没啥差别。为了确定保证你未来所学的Git物超所值,今后断然不会后悔,同时为了打击已经不幸学了SVN的童鞋,本章起初介绍Git的徘徊花级作用之一(注意是之一,也正是后边还有之二,之三……):远程仓库。

Git是分布式版本控制系统,同三个Git仓库,能够分布到分歧的机械上。怎么分布呢?最早,肯定唯有一台机器有1个原始版本库,此后,其他机器能够“克隆”这些原始版本库,而且每台机器的版本库其实都以同一的,并从未先后之分。

你一定会想,至少须要两台机械才能玩远程库不是?不过小编唯有一台微机,怎么玩?

实在一台微型总计机上也是足以仿造四个本子库的,只要不在同三个目录下。可是,现实生活中是不会有人这么傻的在一台微型总括机上搞多少个长途库玩,因为一台总计机上搞多少个长途库完全没有意思,而且硬盘挂了会造成全体库都挂掉,所以本身也不报告你在一台总计机上怎么克朗多少个仓库。

事实上情状屡屡是那般,找一台电脑充当服务器的角色,每一天24钟头开机,其余各种人都从那么些“服务器”仓库克隆一份到自个儿的微处理器上,并且各自把各自的交由推送到服务器仓Curry,也从服务器仓库中拉取他人的提交。

完全能够友善搭建一台运营Git的服务器,不过当下,为了学Git先搭个服务器相对是小题大做。幸而那一个世界上有个叫GitHub的神奇的网站,从名字就足以看看,那几个网站就是提供Git仓库托管服务的,所以,只要注册3个GitHub账号,就足以防费获得Git远程仓库。

在此起彼伏读书后续内容前,请自行注册GitHub账号。由于你的当地Git仓库和GitHub仓库之间的传导是因此SSH加密的,所以,须求或多或少安装:

第一步:创设SSH
Key。在用户主目录下,看看有没有.ssh目录,假诺有,再看看那些目录下有没有id_rsaid_rsa.pub那多少个公文,假诺已经有了,可直接跳到下一步。若是没有,打开Shell(Windows下开拓Git
Bash),创立SSH Key:

1
ssh-keygen -t rsa -C "youremail@example.com"

您供给把邮件地址换来你协调的邮件地址,然后共同回车,使用私下认可值即可,由于这几个Key也不是用以军事指标,所以也无需安装密码。

假设一切顺遂的话,能够在用户主目录里找到.ssh目录,里面有id_rsaid_rsa.pub五个公文,那四个正是SSH
Key的秘钥对,id_rsa是私钥,无法泄揭穿来,id_rsa.pub是公钥,能够放心地告知任哪个人。

第2步:登陆GitHub,打开“Account settings”,“SSH Keys”页面:

下一场,点“Add SSH
Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文本的内容:

图片 4

点“Add Key”,你就活该看到已经增进的Key

为何GitHub必要SSH
Key呢?因为GitHub要求识别出您推送的提交确实是你推送的,而不是旁人冒充的,而Git帮助SSH协议,所以,GitHub只要知道了你的公钥,就能够肯定只有您自个儿才能推送。

理所当然,GitHub允许你添加多少个Key。假定你有多少处理器,你说话在公司提交,一会儿在家里提交,只要把每台电脑的Key都丰硕到GitHub,就足以在每台微型总括机上往GitHub推送了。

末尾友情提示,在GitHub上免费托管的Git仓库,任什么人都得以见到喔(但唯有你协调才能改)。所以,不要把敏感新闻放进去。

如果你不想让外人见到Git库,有八个点子,三个是交点爱护费,让GitHub把公开的库房变成私有的,那样外人就看不见了(不可读更不可写)。另3个方法是祥和入手,搭二个Git服务器,因为是您本人的Git服务器,所以外人也是看不见的。那一个格局大家前面会讲到的,非凡不难,集团里面支出必备。

管教您持有3个GitHub账号后,我们就即将开首远程仓库的上学。

  

8.1 创立远程仓库 

现今的情形是,你早就在地头创设了二个Git仓库后,又想在GitHub创造1个Git仓库,并且让那七个仓库进行长距离同步,那样,GitHub上的仓库既能够用作备份,又足以让别的人通过该仓库来合作,真是一举多得。

先是,登陆GitHub,然后,在右上角找到“New
repository”按钮,创设三个新的库房:

图片 5

 图片 6

 

 

创办好的仓库

图片 7

 

此时此刻,在GitHub上的那些oldboy_website仓库还是空的,GitHub告诉大家,能够从那些库房克隆出新的库房,也得以把一个已有些地点仓库与之提到,然后,把地面仓库的始末推送到GitHub仓库。

今昔,大家依据GitHub的提示,在当地已部分git_trainning仓库下运作命令:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git remote add origin git@github.com:triaquae/oldboy_website.git #添加远程仓库
$ git push -u origin master #推到远程
 
The authenticity of host 'github.com (192.30.253.113)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)? yes   #第一次推会出现,写yes
Warning: Permanently added 'github.com,192.30.253.113' (RSA) to the list of known hosts.
Counting objects: 20, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (20/20), 1.76 KiB | 0 bytes/sdone.
Total 20 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), done.
To git@github.com:triaquae/oldboy_website.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

请千万注意,把地点的triaquae替换到你协调的GitHub账户名,不然,你在该地关联的正是自个儿的远程库,关联不奇怪,不过你未来推送是推不上来的,因为您的SSH
Key公钥不在小编的账户列表中。

添加后,远程库的名字就是origin,那是Git暗中认可的叫法,也得以改成别的,但是origin其一名字一看就通晓是远程库。

把本地库的内容推送到长途,用git push一声令下,实际上是把最近支行master推送到长途。  

 

那时刷新远程仓库页面, 就见到了你刚从本土推上来的代码了

图片 8

从未来起,只要本地作了付出,就足以由此命令:

1
$ git push origin master

what ? 不信?那帮您试一下吧

创办二个index.html文件,同时上传到长途

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ vim index.html
$ git add .
$ git commit -m "add home page"
 
[master 8675486] add home page
 file changed, 6 insertions(+)
 create mode 100644 index.html
 
$ git push origin master #推到远程
 
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 362 bytes | 0 bytes/sdone.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:triaquae/oldboy_website.git
   03df00a..8675486  master -> master

下一场刷新下远程仓库页面,就见到您的新创造的公文了

图片 9

 

8.2 从远程Cook隆  

咱俩讲了先有当地库,后有长途库的时候,怎样关联远程库。

于今,假设大家从零费用,那么最棒的格局是先创制远程库,然后,从远程Cook隆。

先是,登陆GitHub,成立一个新的堆栈,名字叫gitskills

图片 10

大家勾选Initialize this repository with a README,那样GitHub会自动为大家创设一个README.md文本。创设完结后,能够看看README.md文件:

  

图片 11

现行反革命,远程库已经准备好了,下一步是用命令git clone克隆二个本土库:

图片 12

在地面找一个你想存放这么些远程仓库的目录,然后在本地命令行用git clone
命令来克隆这几个远程库

1
2
3
4
5
6
7
8
9
10
11
$ git clone git@github.com:triaquae/gitskills.git
Cloning into 'gitskills'...
Warning: Permanently added the RSA host key for IP address '192.30.253.112' to the list of known hosts.
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
Checking connectivity... done.
 
cd gitskills/  #进入刚clone下来的目录
ls
README.md

一经有多少人合作开发,那么每种人分头从远程克隆一份就能够了。

你大概还留意到,GitHub给出的地址不止二个,还能够用https://github.com/triaquae/gitskills.git 那样的地址。实际上,Git协理七种说道,默许的git://行使ssh,但也得以行使https等其余协商。

使用https而外速度慢以外,还有个最大的难为是历次推送都无法不输入口令,不过在某个只绽放http端口的合作社里面就不可能利用ssh共谋而不得不用https

 

9. 分支管理  

支行正是科学幻想电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另3个您正在另三个平行宇宙里努力学习SVN。

比方多少个平行宇宙互不困扰,那对前几日的你也没啥影响。然则,在某些时间点,多少个平行宇宙合并了,结果,你既学会了Git又学会了SVN!

图片 13

 

 

分层在事实上中有哪些用吧?假诺你准备付出二个新作用,可是急需两周才能到位,第柒日你写了一半的代码,如若立刻交给,由于代码还没写完,不完全的代码库会促成外人不可能办事了。若是等代码全体写完再一回提交,又存在丢失每日进程的壮烈风险。

今日有了分支,就无须怕了。你创设了3个属于您协调的支行,旁人看不到,还一连在本来的分段上健康工作,而你在投机的分层上行事,想付出就交由,直到开发实现后,再2遍性统一到原来的道岔上,那样,既安全,又不影响旁人做事。

其余版本控制系统如SVN等都有分支管理,可是用过之后您会发现,那个版本控制系统成立和切换分支比蜗牛还慢,简直令人不可能忍受,结果分支作用成了安放,我们都不去用。

但Git的分层是特殊的,无论创立、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文本依旧1万个文本。

 

9.1 创制与联合分支 

在攻读版本回退部分时,你早就知晓,每一遍提交,Git都把它们串成一条时间线,那条时间线就是1个拨出。结束到日前,唯有一条时间线,在Git里,那个分支叫主分支,即master分支。HEAD严谨来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD本着的就是当下支行。

一早先的时候,master分段是一条线,Git用master本着最新的交付,再用HEAD指向master,就能显明当前支行,以及当前支行的提交点:

图片 14

 

老是提交,master分段都会上前移动一步,那样,随着你不休提交,master分层的线也更为长, 当大家创造新的支行,例如dev时,Git新建了3个指南针叫dev,指向master同一的交付,再把HEAD指向dev,就象征如今支行在dev上: 

图片 15

比方我们在dev上的工作实现了,就足以把dev合并到master上。Git怎么统一呢?最简单易行的方法,便是直接把master指向dev的近年来交给,就做到了统一:

图片 16

从而Git合并分支也神速!就修改指针,工作区内容也不变!

合并完分支后,甚至能够去除dev分支。删除dev分层正是把dev指南针给删掉,删掉后,我们就剩下了一条master分支:

图片 17

真是太神奇了,你看得出来有个别提交是通过分支达成的吗?

 

上面开首实战

首先,大家制造dev分段,然后切换来dev分支:

1
2
$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b参数表示创造并切换,相当于以下两条命令:

1
2
3
$ git branch dev
$ git checkout dev
Switched to branch 'dev'

然后,用git branch指令查看当前支行:

1
2
3
$ git branch
* dev
  master

git branch指令会列出富有支行,当前支行前面会标三个*号。

下一场,咱们就足以在dev支行上健康提交,比如对readme.txt做个修改,加上一行:

1
Creating a new branch is quick.

下一场交到:

1
2
3
4
$ git add readme.txt
$ git commit -m "branch test"
[dev fec145a] branch test
 file changed, 1 insertion(+)

现在,dev分段的行事成就,大家就能够切换回master分支:

1
2
$ git checkout master
Switched to branch 'master'

切换回master分段后,再查看二个readme.txt文件,刚才添加的始末不见了!因为非凡提交是在dev分支上,而master分层此刻的提交点并从未变:

图片 18

现在,我们把dev分段的劳作成果合并到master分支上:

1
2
3
4
5
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
 readme.txt |    1 +
 file changed, 1 insertion(+)

git merge指令用于合并钦命分支到当下支行。合并后,再查看readme.txt的始末,就能够看到,和dev分层的流行提交是完全相同的。

瞩目到地点的Fast-forward信息,Git告诉大家,这一次合并是“快进情势”,也正是一贯把master指向dev的日前付出,所以集合速度特别快。

自然,也不是每一趟合并都能Fast-forward,大家后边会讲别的艺术的合并。

集合完结后,就足以放心地删除dev分支了:

1
2
$ git branch -d dev
Deleted branch dev (was fec145a).

删除后,查看branch,就只剩余master分支了:

1
2
$ git branch
* master

因为创设、合并和删除分支一点也一点也不慢,所以Git鼓励你采纳分支达成有个别职务,合并后再删掉分支,那和直接在master支行上行事功用是同样的,但经过更安全。

 

9.2 解决争辨

人生比不上意之事十之八九,合并分支往往也不是顺遂的。

居安虑危新的feature1分段,继续大家的新支行开发:

1
2
$ git checkout -b feature1
Switched to a new branch 'feature1'

修改readme.txt最终一行,改为:

1
added this line from branch feature 1

feature1分层上付出:

$ git add readme.txt 
$ git commit -m "add feature"
[feature1 75a857c] AND simple
 1 file changed, 1 insertion(+), 1 deletion(-)

切换到master分支:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.

Git还会活动指示大家当前master支行比远程的master分层要超前3个提交。

master分段上把readme.txt文件的结尾一行改为:

1
added this line from master

提交:

$ git add readme.txt 
$ git commit -m "master update"
[master 400b400] & simple
 1 file changed, 1 insertion(+), 1 deletion(-)

现在,master分支和feature1分段各自都各自有新的提交,变成了如此:

图片 19

那种意况下,Git不恐怕执行“急速合并”,只可以试图把个其他修改合并起来,但那种联合就或许会有争辩,我们试试看:

1
2
3
4
$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

果不其然争辨了!Git告诉我们,readme.txt文件存在争执,必须手动消除争论后再提交。git status也足以告知咱们冲突的公文:

1
2
3
4
5
6
7
8
9
10
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       both modified:      readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

大家得以向来查看readme.txt的始末:

1
2
3
4
5
6
7
#git study repo
Creating a new branch is quick.
<<<<<<< HEAD
added this line from master
=======
added this line from branch feature 1
>>>>>>> feature1

Git用<<<<<<<=======>>>>>>>标志出差异分支的始末,大家修改如下后保存:

1
2
3
4
#git study repo
Creating a new branch is quick.
added this line from master
added this line from branch feature 1

再提交

1
2
3
$ git add readme.txt
$ git commit -m "conflict fixed"
[master 59bc1cb] conflict fixed

现在,master分支和feature1分段变成了下图所示:

图片 20

用带参数的git log也足以看到分支的集合情况:

1
2
3
4
5
6
7
8
$ git log --graph --pretty=oneline
*   feedd786cad3e18323a41846fcc1b0d52fc0c98e fix conflict
|\ 
| * 01f8f8d168e113fac9fbe24c4cfa6d4c351a9821 update from branch
* | 743ccee30f3d74f1993f17e7312032b7399b1306 from master
|/ 
* edfbc29982927236596539e0f1971b0575f803c0 branch test
* 8675486bfeeb340914369e80d2cfcf3e854e88a3 add home page

  

9.3 分支策略

在其实开支中,大家应有根据多少个主导规则开展分层管理:

首先,master分段应该是不行安静的,也便是仅用来发表新本子,平常无法在上面干活;

那在哪干活呢?干活都在dev分段上,也便是说,dev支行是不安定的,到有个别时候,比如1.0本子宣布时,再把dev支行合并到master上,在master分层发表1.0本子;

您和您的伴儿们种种人都在dev分段上行事,每种人都有友好的道岔,时不时地往dev分段上联合就足以了。

于是,团队合作的道岔看起来就好像那样:

图片 21

 

 

9.4 bug分支  

软件开发中,bug就好像平常便饭一样。有了bug就要求修补,在Git中,由于支行是这样的强硬,所以,每一个bug都得以经过三个新的临时分段来修复,修复后,合并分支,然后将暂且分段删除。

当你收到三个修复3个代号101的bug的职责时,很自然地,你想创建叁个拨出issue-101来修补它,可是,等等,当前正值dev上实行的干活还未曾交给:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git status
# On branch dev
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   hello.py
#
# 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:   readme.txt
#

  

并不是你不想付出,而是工作只实行到4/8,还无法交付,估量完结还需1天时间。不过,必须在多个钟头内修复该bug,怎么办?

幸而,Git还提供了二个stash职能,能够把当前工作现场“储藏”起来,等现在复苏现场后继续工作:

1
2
3
$ git stash
Saved working directory and index state WIP on dev: 6224937 add merge
HEAD is now at 6224937 add merge

现在,用git status查看工作区,正是干净的(除非有没有被Git管理的文本),由此得以放心地创建分支来修复bug。

第三鲜明要在哪个分支上修复bug,假定需求在master分段上修复,就从master创设一时分段:

1
2
3
4
5
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
$ git checkout -b issue-101
Switched to a new branch 'issue-101'

后天修复bug,供给把“Git is free software …”改为“Git is a free software
…”,然后交到:

1
2
3
4
$ git add readme.txt
$ git commit -m "fix bug 101"
[issue-101 cc17032] fix bug 101
 file changed, 1 insertion(+), 1 deletion(-)

修复完结后,切换来master分段,并形成联合,最后删除issue-101分支:

1
2
3
4
5
6
7
8
9
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 2 commits.
$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
 readme.txt |    2 +-
 file changed, 1 insertion(+), 1 deletion(-)
$ git branch -d issue-101
Deleted branch issue-101 (was cc17032).

  

太棒了,原布署五个钟头的bug修复只花了四分钟!现在,是时候跟着回到dev分层干活了!

1
2
3
4
5
$ git checkout dev
Switched to branch 'dev'
$ git status
# On branch dev
nothing to commit (working directory clean)

  

工作区是干净的,刚才的劳作现场存到哪去了?用git stash list命令看看:

1
2
$ git stash list
stash@{0}: WIP on dev: 6224937 add merge

行事现场还在,Git把stash内容存在有些地点了,不过须要恢复生机一下,有五个情势:

一是用git stash apply回复,可是还原后,stash内容并不删除,你必要用git stash drop来删除;

另一种艺术是用git stash pop,苏醒的同时把stash内容也删了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git stash pop
# On branch dev
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   hello.py
#
# 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:   readme.txt
#
Dropped refs/stash@{0} (f624f8e5f082f2df2bed8a4e09c12fd2943bdd40)

再用git stash list翻开,就看不到任何stash内容了:

1
$ git stash list

您可以频繁stash,复苏的时候,先用git stash list翻看,然后还原内定的stash,用命令:

1
$ git stash apply stash@{0}

 

  

 

10. 两个人合营  

当你从远程仓库克隆时,实际上Git自动把当地的master分层和远程的master分段对应起来了,并且,远程仓库的暗中认可名称是origin

要翻看远程库的新闻,用git remote

1
2
$ git remote
origin

或者,用git remote -v突显更详尽的新闻:

1
2
3
$ git remote -v
origin  git@github.com:triaquae/gitskills.git (fetch)
origin  git@github.com:triaquae/gitskills.git (push)  

地方显示了能够抓取和推送的origin的地点。若是没有推送权限,就看不到push的地方。

10.1 推送分支

推送分支,正是把该支行上的有所地点提交推送到远程库。推送时,要钦定地点分支,那样,Git就会把该支行推送到远程库对应的长距离分支上:

1
$ git push origin master

假若要推送别的分支,比如dev,就改成:

1
$ git push origin dev

可是,并不是自然要把当地分支往远程推送,那么,哪些分支必要推送,哪些不要求吗?

  • master分层是主分支,由此要时时与长途同步;

  • dev分层是开发分支,团队拥有成员都需求在上头工作,所以也亟需与长途同步;

  • bug分支只用于在本地修复bug,就没供给推到远程了,除非老董要探望你周周详底修复了多少个bug;

  • feature分支是不是推到远程,取决于你是或不是和你的小伙伴协作在上头开发。

显而易见,正是在Git中,分支完全可以在该地本身藏着玩,是还是不是推送,视你的心怀而定!

10.2 抓取分支

几个人搭档时,大家都会往masterdev支行上推送各自的修改。

明天,模拟贰个您的小伙伴,能够在另一台微型总计机(注意要把SSH
Key添加到GitHub)恐怕千篇一律台计算机的另一个索引下仿制:

1
2
3
4
5
6
7
$ git clone git@github.com:triaquae/gitskills.git
Cloning into 'gitskills'...
remote: Counting objects: 16, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 16 (delta 0), reused 10 (delta 0), pack-reused 0
Receiving objects: 100% (16/16), done.
Checking connectivity... done.

当您的同伴从远程库clone时,暗中同意情形下,你的同伙只赏心悦目看地面包车型地铁master分段。不信能够用git branch命令看看:

1
2
$ git branch
* master

最近,你的伙伴要在dev支行上支付,就亟须创立远程origindev支行到当地,于是她用那些命令创建本地dev分支:

1
$ git checkout -b dev origin/dev

今昔,他就足以在dev上接轨修改,然后,时不时地把dev分支push到远程:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git add .
$ git commit -m "small updates"
 
[dev f1b762e] small updates
 2 files changed, 5 insertions(+), 1 deletion(-)
Alexs-MacBook-Pro:gitskills alex$ git push origin dev
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 438 bytes | 0 bytes/sdone.
Total 4 (delta 0), reused 0 (delta 0)
To git@github.com:triaquae/gitskills.git
   33ec6b4..f1b762e  dev -> dev

  

你的小伙伴已经向origin/dev分支推送了他的提交,而刚好你也对同样的文件作了修改,并试图推送:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git add .
$ git commit -m "add Dog class"
[dev 7e7b1bf] add Dog class
 2 files changed, 7 insertions(+)
 
 
$ git push origin dev
 
To git@github.com:triaquae/gitskills.git
 ! [rejected]        dev -> dev (fetch first)
error: failed to push some refs to 'git@github.com:triaquae/gitskills.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again. #提示你了,先把远程最新的拉下来再提交你的
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

推送失利,因为你的同伴的新式提交和您准备推送的交付有争辩,消除办法也很简短,Git已经提示大家,先用git pull把新型的交由从origin/dev抓下来,然后,在该地合并,化解冲突,再推

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git pull
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), done.
From github.com:triaquae/gitskills
   33ec6b4..f1b762e  dev        -> origin/dev
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
 
    git pull <remote> <branch>
 
If you wish to set tracking information for this branch you can do so with:
 
    git branch --set-upstream-to=origin/<branch> dev

git pull也破产了,原因是不曾点名地点dev分段与远程origin/dev支行的链接,依据提醒,设置devorigin/dev的链接:

1
2
$ git branch --set-upstream-to=origin/dev dev
Branch dev set up to track remote branch dev from origin.

再pull:

1
2
3
4
5
6
$ git pull
Auto-merging hello.py
CONFLICT (content): Merge conflict in hello.py
Auto-merging branch_test.md
CONFLICT (content): Merge conflict in branch_test.md
Automatic merge failed; fix conflicts and then commit the result.

这回git pull成功,不过合并有争辨,供给手动消除,化解的章程和分层管理中的消除抵触完全平等。解决后,提交,再push:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git add .
$ git commit -m "merge & fix hello.py"
[dev 93e28e3] merge & fix hello.py
 
$ git push origin dev
 
Counting objects: 8, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 819 bytes | 0 bytes/sdone.
Total 8 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To git@github.com:triaquae/gitskills.git
   f1b762e..93e28e3  dev -> dev

 

为此,多少人合营的工作形式平常是如此:

  1. 首先,可以试图用git push origin branch-name推送自身的修改;

  2. 比方推送战败,则因为远程分支比你的本土更新,须要先用git pull精算合并;

  3. 只要统一有争论,则化解争辨,并在当地提交;

  4. 不曾争持恐怕消除掉争持后,再用git push origin branch-name推送就能学有所成!

如果git pull提醒“no tracking
information”,则证实地方分支和长距离分支的链接关系并未成立,用命令git branch --set-upstream branch-name origin/branch-name

那正是四人搭档的工作格局,一旦熟识了,就极度简单。

  

  

11. github使用

小编们一向用GitHub作为免费的长距离仓库,若是是个人的开源项目,放到GitHub上是一点一滴没有毛病的。其实GitHub还是八个开源合作社区,通过GitHub,既能够令人家到场你的开源项目,也能够参预外人的开源项目。

在GitHub出现从前,开源项目开源不难,但让周边百姓NISSAN参预进来相比困难,因为要参预,就要交给代码,而给每一种想付出代码的公众都开一个账号那是不现实的,由此,群众也仅限于报个bug,就算能改掉bug,也只好把diff文件用邮件发过去,很不便利。

唯独在GitHub上,利用Git极其强大的仿造和支行功用,广大老百姓群众实在得以率先次自由出席各样开源项目了。

什么样参加3个开源项目呢?比如人气极高的bootstrap项目,那是1个老大有力的CSS框架,你能够访问它的品类主页https://github.com/twbs/bootstrap,点“Fork”就在团结的账号下仿制了三个bootstrap仓库,然后,从友好的账号下clone:

1
git clone git@github.com:michaelliao/bootstrap.git

自然要从自身的账号下clone仓库,那样您才能推送修改。要是从bootstrap的小编的堆栈地址git@github.com:twbs/bootstrap.git克隆,因为从没权限,你将不可能推送修改。

Bootstrap的法定仓库twbs/bootstrap、你在GitHub上克隆的库房my/bootstrap,以及你协调克隆到当地电脑的库房,他们的关联就好像下图展现的那样:

图片 22

 

设若您想修复bootstrap的四个bug,恐怕新增一个效果,立即就能够起来工作,干完后,往本身的堆栈推送。

要是您愿意bootstrap的官方库能接受你的修改,你就能够在GitHub上发起四个pull
request。当然,对方是不是接受你的pull request就不肯定了。

若果您没能力修改bootstrap,但又想要试一把pull
request,那就Fork一下本人的库房:https://github.com/triaquae/gitskills ,创造贰个your-github-id.txt的公文文件,写点自个儿学习Git的感受,然后推送一个pull
request给自个儿,小编会视心绪而定是还是不是接受。

小结

  • 在GitHub上,能够任意Fork开源仓库;

  • 自身具有Fork后的库房的读写权限;

  • 能够推送pull request给官方仓库来贡献代码。

  

  

12. 大意特殊文件.gitignore

些微时候,你不可能不把某个文件放到Git工作目录中,但又不能够交付它们,比如保留了数据库密码的铺排文件啦,等等,每一回git status都会呈现Untracked files ...,有焦虑症的童鞋心里自然不爽。

幸亏Git考虑到了豪门的感触,那几个难点消除起来也不会细小略,在Git工作区的根目录下开创二个奇异的.gitignore文件,然后把要不经意的文本名填进去,Git就会活动忽略那一个文件。

不要求开头写.gitignore文件,GitHub已经为大家准备了各类配置文件,只要求整合一下就能够利用了。全数配置文件能够一直在线浏览:https://github.com/github/gitignore

马虎文件的标准化是:

  1. 忽视操作系统自动生成的文件,比如缩略图等;
  2. 马虎编写翻译生成的中等文件、可执行文件等,也正是假诺3个文书是经过另1个文书自动生成的,那自动生成的文本就没要求放进版本库,比如Java编写翻译发生的.class文件;
  3. 忽视你协调的涵盖敏感音讯的布局文件,比如存放口令的布局文件。

举个例证:

一经你在Windows下实行Python开发,Windows会自动在有图表的目录下转移隐藏的缩略图文件,若是有自定义目录,目录下就会有Desktop.ini文本,由此你必要忽略Windows自动生成的垃圾文件:

1
2
3
4
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini

然后,继续忽略Python编写翻译爆发的.pyc.pyodist等文件或目录:

1
2
3
4
5
6
7
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build

丰硕你协调定义的文件,最后获得八个总体的.gitignore文本,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
 
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
 
# My configurations:
db.ini
deploy_key_rsa

最后一步正是把.gitignore也交由到Git,就成功了!当然检验.gitignore的专业是git status一声令下是否说working directory clean

应用Windows的童鞋注意了,要是您在能源管理器里新建四个.gitignore文本,它会充足弱智地提醒您必须输入文件名,不过在文件编辑器里“保存”或许“另存为”就足以把公文保留为.gitignore了。

稍稍时候,你想添加一个文本到Git,但意识充分不了,原因是那些文件被.gitignore忽略了:

1
2
3
4
$ git add App.class
The following paths are ignored by one of your .gitignore files:
App.class
Use -f if you really want to add them.

借使您真的想添加该文件,能够用-f强制添加到Git:

1
$ git add -f App.class

要么您意识,恐怕是.gitignore写得有毛病,须求找出来到底哪些规则写错了,能够用git check-ignore指令检查:

1
2
$ git check-ignore -v App.class
.gitignore:3:*.class    App.class  

Git会告诉大家,.gitignore的第叁行规则忽略了该公文,于是大家就足以领略应该修订哪个规则。

小结

  • 疏忽某个文件时,供给编写制定.gitignore

  • .gitignore文件本人要放权版本Curry,并且可以对.gitignore做版本管理!

  

  

  

上述小说大批量参阅或转发自: http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
 

相关文章