git 的一些用法

###1,建立与合并分支git

1,原理:每次提交,git把版本串成一条时间线这条时间线就是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来讲不是指向提交,而是指向master,master才是指向提交的,因此,HEAD指向的就是当前分支。github

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能肯定当前分支,以及当前分支的提交点:shell

1-1

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也愈来愈长:数据库

当咱们建立新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:vim

1-2

你看,Git建立一个分支很快,由于除了增长一个dev指针,改改HEAD的指向,工做区的文件都没有任何变化!安全

不过,从如今开始,对工做区的修改和提交就是针对dev分支了,好比新提交一次后,dev指针往前移动一步,而master指针不变:app

假如咱们在dev上的工做完成了,就能够把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:编辑器

因此Git合并分支也很快!就改改指针,工做区内容也不变!fetch

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

2,实战:

首先,咱们建立dev分支,而后切换到dev分支:

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

git checkout命令加上-b参数表示建立并切换,至关于如下两条命令:

$ git branch dev
$ git checkout dev	
Switched to branch 'dev'

而后,用git branch命令查看当前分支:

$ git branch
* dev
  master

git branch命令会列出全部分支,当前分支前面会标一个*号。

而后,咱们就能够在dev分支上正常提交,好比对readme.txt作个修改,加上一行:

Creating a new branch is quick.

而后提交:

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

如今,dev分支的工做完成,咱们就能够切换回master分支:

$ git checkout master
Switched to branch 'master'

切换回master分支后,再查看一个readme.txt文件,刚才添加的内容不见了!由于那个提交是在dev分支上,而master分支此刻的提交点并无变:

如今,咱们把dev分支的工做成果合并到master分支上:

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

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就能够看到,和dev分支的最新提交是彻底同样的。

注意到上面的Fast-forward信息,Git告诉咱们,此次合并是“快进模式”,也就是直接把master指向dev的当前提交,因此合并速度很是快。

固然,也不是每次合并都能Fast-forward,咱们后面会讲其余方式的合并。

合并完成后,就能够放心地删除dev分支了:

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

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

$ git branch
* master

由于建立、合并和删除分支很是快,因此Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工做效果是同样的,但过程更安全。

###2,解决冲突

人生不如意之事十之八九,合并分支每每也不是一路顺风的。

准备新的feature1分支,继续咱们的新分支开发:

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

修改readme.txt最后一行,改成:

Creating a new branch is quick AND simple.

在feature1分支上提交:

$ git add readme.txt 
$ git commit -m "AND simple"
[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分支要超前1个提交。

在master分支上把readme.txt文件的最后一行改成:

Creating a new branch is quick & simple. 提交:

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

如今,master分支和feature1分支各自都分别有新的提交,变成了这样:

这种状况下,Git没法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,咱们试试看:

$ 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也能够告诉咱们冲突的文件:

$ 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的内容:

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.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
Git用<<<<<<<,=======,>>>>>>>标记出不一样分支的内容,咱们修改以下后保存:

Creating a new branch is quick and simple.

再提交:

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

如今,master分支和feature1分支变成了下图所示:

用带参数的git log也能够看到分支的合并状况:

$ git log --graph --pretty=oneline --abbrev-commit
*   59bc1cb conflict fixed
|\
| * 75a857c AND simple
* | 400b400 & simple
|/
* fec145a branch test
...

最后,删除feature1分支:

$ git branch -d feature1
Deleted branch feature1 (was 75a857c).

工做完成。

###多人协做

当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,而且,远程仓库的默认名称是origin。

要查看远程库的信息,用git remote:

$ git remote
origin

或者,用git remote -v显示更详细的信息:

$ git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)

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

###3,推送分支

推送分支,就是把该分支上的全部本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

$ git push origin master

若是要推送其余分支,好比dev,就改为:

$ git push origin dev

可是,并非必定要把本地分支往远程推送,那么,哪些分支须要推送,哪些不须要呢?

master分支是主分支,所以要时刻与远程同步;

dev分支是开发分支,团队全部成员都须要在上面工做,因此也须要与远程同步;

bug分支只用于在本地修复bug,就不必推到远程了,除非老板要看看你每周到底修复了几个bug;

feature分支是否推到远程,取决于你是否和你的小伙伴合做在上面开发。

总之,就是在Git中,分支彻底能够在本地本身藏着玩,是否推送,视你的心情而定!

###4,忽略特殊文件

有些时候,你必须把某些文件放到Git工做目录中,但又不能提交它们,好比保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files ...,有强迫症的童鞋内心确定不爽。

好在Git考虑到了你们的感觉,这个问题解决起来也很简单,在Git工做区的根目录下建立一个特殊的.gitignore文件,而后把要忽略的文件名填进去,Git就会自动忽略这些文件。

不须要从头写.gitignore文件,GitHub已经为咱们准备了各类配置文件,只须要组合一下就可使用了。全部配置文件能够直接在线浏览:https://github.com/github/gitignore

忽略文件的原则是:

忽略操做系统自动生成的文件,好比缩略图等; 忽略编译生成的中间文件、可执行文件等,也就是若是一个文件是经过另外一个文件自动生成的,那自动生成的文件就不必放进版本库,好比Java编译产生的.class文件; 忽略你本身的带有敏感信息的配置文件,好比存放口令的配置文件。 举个例子:

假设你在Windows下进行Python开发,Windows会自动在有图片的目录下生成隐藏的缩略图文件,若是有自定义目录,目录下就会有Desktop.ini文件,所以你须要忽略Windows自动生成的垃圾文件:

# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini

而后,继续忽略Python编译产生的.pyc、.pyo、dist等文件或目录:

# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build

加上你本身定义的文件,最终获得一个完整的.gitignore文件,内容以下:

# 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忽略了:

$ 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:

$ git add -f App.class

或者你发现,多是.gitignore写得有问题,须要找出来到底哪一个规则写错了,能够用git check-ignore命令检查:

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

Git会告诉咱们,.gitignore的第3行规则忽略了该文件,因而咱们就能够知道应该修订哪一个规则。

小结

忽略某些文件时,须要编写.gitignore;

.gitignore文件自己要放到版本库里,而且能够对.gitignore作版本管理!

###5,vim简单操做

####正常模式 正常模式通常用于浏览文件,也包括一些复制、粘贴、删除等操做。这时击键时, 通常的键/键组合会被当成功能键,而不会键入对应的字符。

在这个模式下,咱们可能经过键盘在文本中跳来跳去,跳动的范围从小到大是字符、 单词、行、句子、段落和屏幕。

启动vim后默认位于正常模式。不论位于什么模式,按下<Esc>键(有时须要按两下) 都会进入正常模式。

####插入模式 在正常模式中按下i, I, a, A等键(后面系列文章会详细介绍),会进入插入模式。 如今只用记住按i键会进行插入模式。插入模式中,击键时会写入相应的字符。

命令模式 在正常模式中,按下:(冒号)键,会进入命令模式。在命令模式中能够执行 一些输入并执行一些vim或插件提供的指令,就像在shell里同样。这些指令包括 设置环境、文件操做、调用某个功能等等。

可视模式 在正常模式按下v, V, <Ctrl>+v,能够进入可视模式。可视模式中的 操做有点像拿鼠标进行操做,选择文本的时候有一种鼠标选择的即视感,有时候 会很方便。

####命令模式下的简单命令

:w                 将编辑的内容写入原始文件,用来保存编辑的中间结果
:wq                将编辑的内容写入原始文件并退出编辑程序(至关于 ZZ 命令)
:w file            将编辑的内容写入 file 文件,保持原有文件的内容不变
:a,bw file         将第 a 行至第 b 行的内容写入 file 文件
:r file            读取 file 文件的内容,插入当前光标所在行的后面
:e file            编辑新文件 file 代替原有内容
:f file            将当前文件重命名为 file
:f                 打印当前文件名称和状态,如文件的行数、光标所在的行号等

###6,一个小问题:Git warning:LF will be replaced by CRLF in readme.txt的缘由与解决方案

首先问题出在不一样操做系统所使用的换行符是不同的,下面罗列一下三大主流操做系统的换行符:

Uinx/Linux采用换行符LF表示下一行(LF:LineFeed,中文意思是换行);

Dos和Windows采用回车+换行CRLF表示下一行 (CRLF:CarriageReturn LineFeed,中文意思是回车换行);

Mac OS采用回车CR表示下一行(CR:CarriageReturn,中文意思是回车)。

在Git中,能够经过如下命令来显示当前你的Git中采起哪一种对待换行符的方式

$ git config core.autocrlf

此命令会有三个输出,“true”,“false”或者“input”

为true时,Git会将你add的全部文件视为文本问价你,将结尾的CRLF转换为LF,而checkout时会再将文件的LF格式转为CRLF格式。

为false时,line endings不作任何改变,文本文件保持其原来的样子。

为input时,add时Git会把CRLF转换为LF,而check时仍旧为LF,因此Windows操做系统不建议设置此值。

解决办法: 将core.autocrlf设为false便可解决这个问题

$ git config --global core.autocrlf false
相关文章
相关标签/搜索