资源精选iOS学习引擎IT圈内那点事儿

Git 菜鸟笔记

2016-10-27  本文已影响568人  IAM四十二

前言##

Git

Git是一款免费、开源的分布式版本控制系统。使用Git可以方便的实现代码版本管理。

平时使用git的时候,也是遇到很多问题,但是每次解决完问题 之后就忘了解决方法,这里特意梳理一下。

实践##

首先,要明白Git不同于SVN(如果你曾使用过的话)。是一种完全不同的设计理念。

下图是git本地操作的简单原理图(图片来自网络搜索)。

Git 本地操作原理

其次,要明白图中绿色、黄色、蓝色三个部分所代表的含义。

基础###

我们首先创建一个目录(上图中绿色的work directory)

mkdir mywork

cd mywork

git status **查看当前git 仓库状态 **

不清楚当前git 仓库是什么状态时,可以使用这个命令,是一个常用的命令。

git init 初始化一个git 仓库

这样就创建了上图中蓝色的git repository

为了方便测试,我们在mywork 目录下创建一个readme.txt 文件,其内容为

readme.txt

git add readme.txt 添加文件到中转区(就是上图中黄色区域),也可以称为暂存区。

这样就相当于上图中操作1

如果add 到中转区的内容不想要了,也可以删除,这个很重要,后面还会说到。

git rm --cached

如果add 内容没问题,就可以提交了。

git commit -m "Version 1.0" 提交文件到本地仓库,并附带提交信息,这点和SVN倒是相似

相当于图中的操作2

git log 查看提交信息

我们可以看一下现在的提交信息:

commit_log

这样,就完成了一次提交。注意这里的commit和SVN中的commit的意义是不同的。

Branch 分支###

git branch 查看当前所处分支

*master 一般情况下,都会在master分支上。

git branch test 创建test 分支

git checkout test 切换到test 分支

Switched to branch 'test'

我们在test 分支对readme.txt 文件做一些修改:

echo 这是在test分支的修改 >> readme.txt

然后将其提交到test branch

git commit -am "test branch commit"

这里由于没有新增文件,这样合并的操作可以一次完成add和commit。如果有新增文件,还是需要单独 add 的。

git log 查看commit 信息

可以查看到当前分支test上目前为止所有的commit 信息。

我们在切换回master分支

git checkout master

这个时候,如果我们用git log 查看一下可以发现,master分支并没有我们在test分支上的提交信息。同时readme.txt 这个文件的内容,也实没有改变。

所以,我们现在需要将test分支的内容合并到master分支上

git merge test

Updating 1f812af..dd7773e
Fast-forward
 readme.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

这个时候,我们再执行git log 就可以看到test 分支上提交的信息了,同时readme.txt 的内容也变成了修改后合并的内容。

现在test如果不再需要其他的开发内容,我们就可以将它删除了

git branch -d test

Deleted branch test (was dd7773e).

提交到远程仓库###

到目前为止,所有的操作都是在本地完成,即便是完成了commit(这个可和Svn的Commit不是一回事)

实际开发中,还需要将commit 之后的内容提交到远程仓库中。

可以在自己的Github 上创建一个git仓库 : https://github.com/USERNAME/GitStudy.git

由于我们已经在本地创建了git仓库,所以现在要做的就是把本地仓库和远程仓库(GitStudy)关联起来。

git remote add origin https://github.com/USERNAME/GitStudy.git

如果你是第一次使用git ,这里可能还需要如下配置

git config --global user.name "Your Name"
git config --global user.email you@email.com

这样,我们本地仓库就和远程仓库关联了,首先,我从需要从远程从库把最新的代码pull下来

pull_from_github

可以看到,这里已经从github把内容更新到了本地。接下,就是最后一步,把我们修改过的内容,提交的远程仓库。这个时候,可以用git status 查看一下本地仓库状态,如果没有需要提交的内容,就可以直接push 了。

push_to_github

这时候 ,我们可以在github看到我们提交的内容了。

解决冲突###

上面的流程,是日常使用git当中最完美的一种,整个过程没有冲突。但是实际开发中,冲突是不可避免的。下面来说一下冲突产生的原因及如何解决。
假设现在有这样一个需求,需要在readme.txt 中添加自己的邮箱地址
同时现在有两个程序员CoderA和CoderB,他们分别以自己的名字创建了分支,并修改了readme.txt。

branch_change

好了,现在切换到master分支开始合并这两个分支的内容:

merge

结果在merge CoderB 分支的时候发生了冲突。这个完全是由于两个分支同时修改同一个文件造成的。
我们打开 readme.txt 文件,看看它的内容:

这是一个测试文本1.0
这是在test分支的修改
<<<<<<< HEAD

"CoderA@163.com" 
=======
"CoderB@163.com" 
>>>>>>> CoderB

现在对冲突就行修改,将readme.txt 内容修改如下

这是一个测试文本1.0
这是在test分支的修改
"CoderA@163.com" 
"CoderB@163.com" 

然后再次提交并push到远程仓库。

git commit -am "conflict reslove"
git push origin master

这样,就完成了一次简单的冲突解决。日常开发中,要尽量避免这种同时修改同一文件的问题。同时,也要养成每天在修改代码之前update的习惯。

后悔药###

有时候commit之后发现,commit的内容有些问题,想回退到之前的某个点。这个时候就可以使用git reset 命令
根据–soft –mixed –hard,会对working tree和index和HEAD进行重置

git reset –mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息

git reset –soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可

git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容

我们首先看一下当前的commit信息:

commit log

现在,如果决定回退到id 位4561f5d65a7ec7d6fc6a411046172509f66761d8 的commit状态。也就是 Merge branch 'master' 的那个节点。

git reset --hard 4561f5d65a7ec7d6fc6a411046172509f66761d8

现在在看readme.txt 发现他已经回退到之前的状态了。因为我们使用了最强大的 --hard。

而且由于我们之前已经将之前的commit 内容提交到了远程仓库(github),所以github提交的内容,也需要强制进行回退。

git push origin HEAD --force

现在我们到github 上会发现,代码已经回退到之前的版本了。

好了,这样就完成了一次代码回退。可以发现,--hard 和 --force 将导致代码内容从本质内容上物理回退。所以,一定要谨慎使用。最好还是使用默认的方式,除非十分确定要回退源码。

.gitignore

使用Git的过程中,一般都会接触到.gitignore 这个文件。顾名思义,这个.gitignore 的作用就是帮助我们忽视一些不必提交的文件,比如编译之后产生的.class 文件,一些本地化的配置文件等。一般来说,IDE 会自动帮我们生成一个这样的文件,配置的内容要不用过多考虑。

但是,我们在使用过程中有时候会发现,这个.gitigore 失效了。我们在commit的过程中,依然会有不需提交的内容出现在提交列表中。这里需要明白,.gitignore 生效的范围是在由 working directory add 到 暂存区的过程中。也就是说,如果在生成.gitignore 之前进行了add 操作,那么.gitignore 将失效。那该如何解决这个问题呢?其实,也很简单,之前我们说过,add 到暂存区的内容,可以删除。因此,我们可以这样

git rm -r -f --cached .

这样我们就强制删除了暂存区(第一幅图中黄色区域)中所有内容,注意,--cached 后面有个点,代表所有文件

这时候,我们再次git add . 然后commit,就会发现.gitignore 生效了。

后话##

很多人接触的第一款版本控制系统并不是Git,而是SVN。个人感觉,二者各有千秋,无所谓那个更好。Git相较于SVN固然强大,但也因为其过于强大,产生问题是会有些复杂,不好解决。所以,SVN如果够用,完全是一个好的选择。

这里简单列举了日常开发中使用过的git命令,及遇到问题的解决方法。截图的时候,使用的电脑不是个人账户,所以就打了马赛克。


上一篇 下一篇

猜你喜欢

热点阅读