git笔记:一篇搞懂git是个什么玩意

一、图解:

1  git是分布式的, 可以各自独立,没有中心cvs svn等是集中式的,因为是分布式的,可以在安装了git的任何机器上创建版本库(没有服务器),但通常拿一个远程库大家共同推送到这个上面(相当于服务器)

2  远程仓库  -- 即另外一个电脑上的仓库

3  工作区和暂存区

工作区有一个隐藏目录.git,这个不算工作区的,而是Git的版本库。
Git的版本库里存了很多东西:
1)其中最重要的就是称为stage(或者叫index)的暂存区,
2)还有Git为我们自动创建的第一个分支master,
3)以及指向master的一个指针叫HEAD。
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到本地仓库的当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

4   分支及作用

作用:假设你准备开发一个新功能,需要10天才能完成,第一天你写了10%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。 如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。


5   Git跟踪并管理的是修改,而非文件 

同一个文件, 第一次修改后 add 到暂存区, 然后再修改, 
那么commit时,只会把暂存区的内容提交到版本库, 之后修改的因为没有add到暂存区, 所以不会被提交
 


二、有很多图形化的git工具,但起初最好先熟悉命令,也很快:

———————————————————————————————————————————————————————————————————————————

1 创建本地仓库:进入一个目录然后git init  (或者从远端 git clone 比如 git clone git@111.222.33.188:/git/android.git/

$ cd xxxdir

$ git init

通过git init命令把这个目录变成Git可以管理的仓库:

当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的


如果是用 git init先创建本地仓库,需要使用git remote add命令用于添加远程主机,然后才能把本地的推送到远程仓库。
$ git remote add <主机名> <网址>


但如果是用 git clone从远程仓库克隆的,那么会自动添加该远程主机

可以使用 git remote -v  来查看

———————————————————————————————————————————————————————————————————————————

2)把文件添加到本地仓库


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

$ git add readme.txt

执行上面的命令,没有任何显示,这就对了,Unix的哲学是没有消息就是好消息,说明添加成功。


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

$ git commit -m "wrote a readme file"

-m 本次提交的说明

———————————————————————————————————————————————————————————————————————————

3)运行git status命令看看结果:(比如修改readme.txt文件后

$ 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.txt

#

no changes added to commit (use "git add" and/or "git commit -a")

git status命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。

———————————————————————————————————————————————————————————————————————————

4)用git diff这个命令查看修改的内容:

$ git diff readme.txt 

diff --git a/readme.txt b/readme.txt

index 46d49bf..9247db6 100644

--- a/readme.txt

+++ b/readme.txt

@@ -1,2 +1,2 @@

-Git is a version control system.

+Git is a distributed version control system.

 Git is free software.


———————————————————————————————————————————————————————————————————————————

5)提交修改 

$ git commit -m "add distributed"

-m 本次提交的说明

———————————————————————————————————————————————————————————————————————————

6git操作日志

$ git log --pretty=oneline

3628164fb26d48395383f8f31179f24e0882e1e0 append GPL

ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed

cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

你看到的一大串类似3628164...882e1e0的是commit id(版本号)


首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100^比较容易数不过来,所以写成HEAD~100

———————————————————————————————————————————————————————————————————————————


7 返回上一个版本

现在,我们要把当前版本“append GPL”回退到上一个版本“add distributed”,就可以使用git reset命令:

$ git reset --hard HEAD^

HEAD is now at ea34578 add distributed


8 从当前版本append GPL,返回上一个版本后,再回到版本append GPL,需要指定id

$ git reset --hard 3628164

HEAD is now at 3628164 append GPL

版本号没必要写全,前几位就可以了,Git会自动去找。


9) 找不到新版本的commit id怎么办?

Git提供了一个命令git reflog用来记录你的每一次命令:

$ git reflog

ea34578 HEAD@{0}: reset: moving to HEAD^

3628164 HEAD@{1}: commit: append GPL

ea34578 HEAD@{2}: commit: add distributed

cb926e7 HEAD@{3}: commit (initial): wrote a readme file

终于舒了口气,第二行显示append GPLcommit id3628164

———————————————————————————————————————————————————————————————————————————

10)用rm命令删除文件:

$ rm test.txt

这个时候,Git会知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:

现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit

$ git rm test.txt

rm 'test.txt'

$ git commit -m "remove test.txt"

现在,文件就从版本库中被删除了。 

另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

$ git checkout -- test.txt

———————————————————————————————————————————————————————————————————————————

11)checkout:丢弃工作区的修改

$git checkout -- readme.txt    (注:命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令)
用本地仓库里的内容覆盖掉工作区的内容,这里有两种情况:

一种是readme.txt修改后还没有被放到暂存区,现在撤销修改,就是用本地仓库里的内容覆盖掉工作区的内容;
一种是readme.txt已经添加到暂存区后,现在撤销修改, 就是用本地仓库里的内容覆盖掉工作区的内容,但暂存区里的修改不会改变


12)把暂存区的修改撤销掉

$ git reset HEAD readme.txt
可以把暂存区的修改撤销掉,重新放回工作区

小结
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交使用:
git reset --hard 3628164
———————————————————————————————————————————————————————————————————————————

13)拉取远程仓库里的更新取到本地:git fetch  和  git pull命令


比如,取回origin主机的master分支。

Git fetch origin master
所取回的更新,会存储在本地主机上 
 
git branch -a 查看存储在本地的所有分支。
 
$ git branch -a
* master                               --这是本地仓库的master分支
  remotes/origin/master     --这是远程仓库的master分支


1.   git fetch:相当于是从远程获取最新版本到本地,不会自动merge合并

Git fetch origin master                     --从远程的origin的master主分支下载最新的版本到origin/master分支上
git log -p master..origin/master      --比较本地仓库的master和远程master的区别
git merge origin/master                   --合并到当前分支
 


2.   git pull:相当于是从远程获取最新版本并merge到本地
 

git pull命令的作用是,取回远程主机某个分支的更新,再与本地的指定分支合并。它的完整格式稍稍有点复杂。

$ git pull <远程主机名> <远程分支名>:<本地分支名>
比如,取回origin主机的next分支,与本地的master分支合并,需要写成下面这样。

$ git pull origin next:master
如果远程分支是与当前分支合并,则冒号后面的部分可以省略。

$ git pull origin next


问题:合并时有冲突如何解决?

http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840202368c74be33fbd884e71b570f2cc3c0d1dcf000

———————————————————————————————————————————————————————————————————————————

14)将本地仓库推送到远程

1.git push命令用于将本地分支的更新,推送到远程主机 

$ git push <远程主机名> <本地分支名>:<远程分支名>
比如:
$ git push origin master
上面命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。

2.如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。

$ git push origin :master
# 等同于
$ git push origin --delete master
上面命令表示删除origin主机的master分支。

3 如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。
$ git push origin
上面命令表示,将当前分支推送到origin主机的对应分支。


4.如果当前分支只有一个追踪分支,那么主机名都可以省略。
$ git push


如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。

这时,如果你一定要推送,可以使用--force选项。

———————————————————————————————————————————————————————————————————————————

15)分支

Git鼓励大量使用分支:

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建+切换分支:git checkout -b <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>


参考:分支




三、使用工具

用SourceTree轻松Git项目图解


http://blog.csdn.net/agul_/article/details/7835786#t0


git checkout .  #本地所有修改的。没有的提交的,都返回到原来的状态
git stash  #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。
git reset --hard HASH  #返回到某个节点,不保留修改。
git reset --soft HASH  #返回到某个节点。保留修改



合并分支时的冲突解决

http://backlogtool.com/git-guide/cn/stepup/stepup2_7.html

http://www.cnblogs.com/sinojelly/archive/2011/08/07/2130172.html

冲突的类型

1 内容冲突

两个用户修改了同一个文件的同一块区域,git会报告内容冲突。我们常见的都是这种

冲突产生后,文件系统中冲突了的文件(这里是test.txt)里面的内容会显示为类似下面这样:
a123
<< << << < HEAD
我修改的内容
== == == =
别人修改的内容
>> >> >> >  6853e5ff961e684d3a6c02d4d06183b5ff330dcc
c
其中:冲突标记<<<<<<< (7个<)与=======之间的内容是我的修改,=======与>>>>>>>之间的内容是别人的修改。
此时,还没有任何其它垃圾文件产生。
 
最简单的编辑冲突的办法,就是直接编辑冲突了的文件(test.txt),把冲突标记删掉,把冲突解决正确


修改完冲突之后,需要重新提交。

$ git add test.txt
$ git commit -m "合并分支"


2 逻辑冲突--git自动处理(合并/应用补丁)成功,但是逻辑上是有问题的。
比如另外一个人修改了文件名,但我还使用老的文件名,这种情况下自动处理是能成功的,但实际上是有问题的。
又比如,函数返回值含义变化,但我还使用老的含义,这种情况自动处理成功,但可能隐藏着重大BUG。这种问题,主要通过自动化测试来保障。所以最好是能够写出比较完备的自动化测试用例。
这种冲突的解决,就是做一次BUG修正。不是真正解决git报告的冲突。




3 树冲突
文件名修改造成的冲突,称为树冲突。
比如,a用户把文件改名为a.c,b用户把同一个文件改名为b.c,那么b将这两个commit合并时,会产生冲突。

$ git status
    added by b:    b.c
    both deleted:   origin-name.c
    added by a:  a.c

如果最终确定用b.c,那么解决办法如下:

git rm a.c
git rm origin-name.c
git add b.c
git commit

树冲突也可以用git mergetool来解决,但整个解决过程是在交互式问答中完成的,用d 删除不要的文件,用c保留需要的文件。
最后执行git commit提交即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值