Git命令备忘录

Git学习笔记

1.Git简介

1.1 Git产生历史

很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?

事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!

你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。

不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。

安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。

Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。

Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。

历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。

1.2 Git特点

A.版本控制
可以解决多人同时开发的代码问题,也可以解决找回历史代码的问题

B.分布式
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。首先找一台电脑充当服务器,每天24小时开机,其他每个人都从这个服务器仓库克隆一份代码到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交,可以自己搭建这台服务器,可以使用GitHub、码云等。

1.3 Git相关网站

2.Git安装和配置

在安装之前,都可以在终端里,查看当前是否已安装和安装的版本:

# 查看git命令是否可用
$ git
# 查看git版本
$ git --version

2.1 Ubuntu

安装命令

$ sudo apt-get install git

2.2 Mac

一:一般情况下,Mac系统都自带了Git,特别是安装了Xcode的情况下,Command Line Tools命令行工具里,是包含Git组件的。

二:一是安装homebrew,然后通过homebrew安装Git,具体方法请参考homebrew的文档:

http://brew.sh/

2.3 Windows

去上节Git官网下载Git客户端即可。

2.4 Git配置

安装完成后,还需要最后一步设置,在命令行输入:

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

注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址

3.创建版本库

3.1 创建版本库

什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”

所以,创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录:

$ mkdir gitTest
$ cd gitTest
$ pwd
/Users/houwan/Desktop/gitTest

最好目录不要有中文,防止出现各种神奇问题

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

$ git init
Initialized empty Git repository in /Users/houwan/Desktop/gitTest/.git/
  • 此时仓库建好了,而且告诉你是一个空的仓库(empty Git repository)
  • .git文件夹是Git来跟踪管理版本库的,默认隐藏,使用ls -al可以看到
  • 不一定必须在空目录下创建Git仓库,选择一个已经有东西的目录也是可以的

3.2 添加文件到版本库

首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。

不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件

因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持

新建一个文件code.txt,并添加一行内容,一定要放到gitTest目录下(子目录也行),用命令创建如下:

$ vi code.txt
# 查看文件内容可以是:
$ cat code.txt

下面把一个文件放到Git仓库只需要两步。
第一步,用命令git add告诉Git,把文件添加到仓库:

$ git add code.txt

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

$ git commit -m '版本1'
[master (root-commit) 0c7efe4] 版本1
 1 file changed, 1 insertion(+)
 create mode 100644 code.txt
  • git commit命令,-m参数可有可无,但是为了理解管理,强烈建议加入版本说明
  • 可以多次add不同的文件,最后再执行一次git commit
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

4.管理和回退

4.1 版本回退

Git的每一次commit都可以称为“快照”,一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作.

使用git log命令查看commit记录:

commit e5fb29481a81fdfcdd65e4080ad99e04b27d8c0d (HEAD -> master)
Author: 侯万 <136557493@qq.com>
Date:   Sun Apr 12 16:28:40 2020 +0800

    版本2

commit 0c7efe4b950670b18d47ad48c833c4f1ab4a0824
Author: 侯万 <136557493@qq.com>
Date:   Sun Apr 12 16:26:54 2020 +0800

    版本1

git log命令显示从最近到最远的提交日志, 如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

$ git log --pretty=oneline
e5fb29481a81fdfcdd65e4080ad99e04b27d8c0d (HEAD -> master) 版本2
0c7efe4b950670b18d47ad48c833c4f1ab4a0824 版本1

这种e5fb...c0d一串字符,就是commit id版本号,和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示。

每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使用可视化工具查看Git历史,就可以更清楚地看到提交历史的时间线:

0001.png

开始回到上一个版本,命令是:

$ git reset --hard HEAD^
HEAD is now at 0c7efe4 版本1

其中HEAD表示当前最新版本,HEAD^表示上一个版本,HEAD^^上上一个版本,也可以使用HEAD~1表示当前版本的前一个版本,HEAD~100表示当前版本的前100版本

此时,又想回到版本2,怎么办?使用如下命令:版本号那么长,其实只复制前7/8位就可以

$ git reset --hard 版本号

如果还能看到之前git log记录,就能复制到对应的版本号,如果看不到的话,使用下面命令查看操作记录:

$ git reflog
0c7efe4 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
e5fb294 HEAD@{1}: commit: 版本2
0c7efe4 (HEAD -> master) HEAD@{2}: commit (initial): 版本1

能看到版本2的版本号是e5fb294,此时,我们使用下面的命令,就能再回到版本2:

$ git reset --hard e5fb294
HEAD is now at e5fb294 版本2

优化显示git log显示:

$ git log --oneline

4.2 工作区和暂存区

工作区
工作区(Working Directory)是电脑中的目录,比如我们的gitTest目录,就是一个工作区

版本库
版本库(Repository):工作区里面的隐藏目录.git就是git的版本库.此文件夹下存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有分支信息、以及指向master的一个指针叫HEAD

0002.png

对比上图,可以发现:

  • git add实际上是把文件修改,添加到暂存区
  • git commit提交更改,实际就是把暂存区的所有内容,提交到当前分支

验证练习,先对code.txt进行内容添加,再新增一个文件:code2.txt,此时,使用git status命令查看:

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

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    code2.txt

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

Git非常情况告诉我们:code.txt被修改了,而code2.txt文件还没有被添加过,所以状态是Untracked

使用命令git add添加,并再次使用git status命令查看:

$ git add code.txt code2.txt
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   code.txt
    new file:   code2.txt

此时,code.txt的修改和新文件code2.txt以及在暂存区(Stage)了。执行git commit可以一次性把暂存区的所有修改,提交到分支。

$ git commit -m "版本3"
$ git status
On branch master
nothing to commit, working tree clean

可以看到,提交之后,工作区就是“干净”的。

4.3 管理修改

这节证明git管理的是修改,而不是文件,这也是git相比其他版本控制系统优秀的地方
第一步,对code.txt添加内容,并提交

$ vi code.txt
$ git add code.txt

此时git status显示内容如下:

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

然后再继续给code.txt添加一行内容,直接commit

$ vi code.txt
$ git commit -m "版本4"

此时按理来说,不管第一次修改,还是第二次修改,都应该提交的,但是执行git status内容如下:

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

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

咦,怎么第二次的修改没有被提交?顾一下操作过程:
第一次修改 > git add > 第二次修改 > git commit

结论:Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

此时,用git diff HEAD -- code.txt命令可以查看工作区和版本库里面最新版本的区别:

$ git diff HEAD -- code.txt
diff --git a/code.txt b/code.txt
index 66f9219..ee99dfb 100644
--- a/code.txt
+++ b/code.txt
@@ -2,3 +2,4 @@ this is the first line
 this is the second line
 this is the third line
 this is the forth line
+this is the 5 linee

可见,第二次修改确实没有被提交。可以继续git addgit commit即可。

4.4 撤销修改

继续上面,第二次没有真正的提交commit,此时想丢弃掉添加的内容,命令如下:

git checkout -- 文件名

git checkout -- file命令中的--很重要,没有--就变成'创建一个新分支'的命令了

执行情况如下:

$ git checkout -- code.txt 
$ git status
On branch master
nothing to commit, working tree clean

发现工作区已经干净了。

上面是修改文件之后,没有git add的情况,下面我们修改文件,并git add到暂存区:

$ vi code.txt
$ git add code.txt
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   code.txt

此时,想要回退撤销,需要下面的命令:(上面输出也提示了)

git reset HEAD 文件名

那么执行过程如下:

$ git reset HEAD code.txt   // 将文件从暂存区,撤回工作区
$ git checkout -- code.txt  // 到工作区后,再丢弃掉修改
$ git status
On branch master
nothing to commit, working tree clean

结论

  • 在工作区撤销(丢弃)命令是:git checkout -- fileName
  • 在暂存区撤销的命令是:git reset HEAD fileName,此时文件在工作区了,然后再修改文件,或者直接丢弃git checkout -- fileName
  • 如果git commit了,想要撤销,命令是git reset --hard 版本号,这个参加4.1版本回退章节,(前提是没有推送到远程库)

4.5 对比文件的不同

命令git diff是列出对比,可以来比较项目中任意两个版本的差异。

$ git diff   // 列出当前没有`git add`的所有修改的内容对比
$ git diff --cached  // 查看已缓存的改动 指已`git add`的内容
$ git git diff HEAD  // 查看已缓存的与未缓存的所有改动

具体某个文件的对比:git diff HEAD -- 文件名

# 列出`code.txt`文件和HEAD上的不同
$ git diff HEAD -- code.txt 

diff --git a/code.txt b/code.txt  // 这里a是指HEAD  b代表当前工作区的
index 66f9219..324317f 100644
--- a/code.txt  // ---代表减少的
+++ b/code.txt  // +++代表增加的
@@ -2,3 +2,4 @@ this is the first line
 this is the second line
 this is the third line
 this is the forth line
+the new line

两个版本中具体某个文件的对比:
A版本号和B版本号某文件的对比:git diff A版本号 B版本号 -- 文件名
这版本和上个版本某文件的对比: git diff HEAD HEAD^ -- 文件名

$ git diff HEAD HEAD^ -- code.txt  // 对比这个版本和上个版本code.txt的不同

diff --git a/code.txt b/code.txt  // 这里a是指HEAD  b代表HEAD^
index 66f9219..01e1274 100644
--- a/code.txt
+++ b/code.txt
@@ -1,4 +1,3 @@
 this is the first line
 this is the second line
 this is the third line
-this is the forth line

如果你要查看当前的工作目录与另外一个分支的差别,你可以用下面的命令执行:

// 这会显示你当前工作目录与另外一个叫'test'分支的差别
$ git diff test
// 你当前工作目录下的lib目录与上次提交之间的差别(或者更准确的 说是在当前分支)
$ git diff HEAD -- ./lib

4.6 删除文件

删除文件,正常的命令删除,或者右键删除即可:

$ rm 文件名

删除之后,要么撤销,要么提交:

$ git add 文件名  # 提交删除改动 到暂存区
$ git rm 文件名  # 提交删除改动 到暂存区
$ git commit -m '删除code.txt'  # 提交到当前分支

$ git checkout -- 文件名  # 撤销删除

4.7 本章总结

创建版本仓库

$ git init  # 生成`.git` 目录

版本创建

$ git add 文件/目录  # 放到暂存区
$ git commit -m '版本说明信息'  # 创建一个版本记录,只是记录了修改

查看版本记录

$ git log

版本回退

$ git reset --hard HEAD^  # HEAD指当前版本,几个^代表前几个版本
$ git reset --hard 版本序列号  

查看操作记录

$ git reflog

工作区、版本库、暂存区

$ 编辑文件都是在工作区
$ git add  # 把工作区的修改放入暂存区
$ git commit  # 把暂存区的修改一次性做一次版本记录

撤销修改

# 1.直接修改工作区的改动
$ git checkout -- 文件
# 2.修改已经添加到暂存区,但是没有`commit`,下面2步
$ git reset HEAD 文件
$ git checkout -- 文件
# 3.已经`commit`
$ git reset --hard HEAD^  # HEAD指当前版本,几个^代表前几个版本
$ git reset --hard 版本序列号  

对比文件不同

# 1.对比工作区和版本库某个文件
$ git diff HEAD -- 文件
# 2.对比两个版本中的文件
$ git diff HEAD HEAD^ -- 文件名

删除文件

$ rm 文件名
$ git rm 文件名  # 添加到暂存区
$ git commit -m '删除文件'  # 提交版本

5.分支管理

5.1 概念

直接查看官方介绍:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B

5.2 创建和合并分支

查看本地所有分支

$ git branch

下面创建一个分支dev并切换到其上进行工作

$ git checkout -b dev
$ git branch  # 查看分支

下面修改一个文件内容code.txt,并提交

$ vim code.text
$ git add code.txt
$ git commit -m 'dev分支提交'
$ git log --pretty=oneline  # 查看提交记录

dev分支工作完成,切换回master分支:

$ git checkout master
Switched to branch 'master'
$ cat code.txt  # 查看code.text文件内容
$ git log --pretty=oneline  # 查看提交记录

发现此时master分支没有dev分支上改变的内容,需要合并分支:

$ git merge dev
Updating 5f63379..2667394
Fast-forward
 code.txt | 1 +
 1 file changed, 1 insertion(+)
 $ git log --pretty=oneline

上面的输出里有Fast-forward,说明这次合并是快速模式,也就不是直接把master指向dev的当前提交,所以合并速度非常快

合并完成之后,可以放心的删除dev分支了:

$ git branch -d dev  # 删除dev分支
$ git branch  # 查看分支列表

本章小结:

  • 查看分支:git branch
  • 创建分支:git branch <name>
  • 切换分支:git checkout <name>
  • 创建+切换分支:git checkout -b <name>
  • 合并某分支到当前分支:git merge <name>
  • 删除分支:git branch -d <name>

5.3 解决冲突

合并分支很多时候,并不是一帆风顺的!

1.再创建一个dev分支,并修改文件code.txt

$ git checkout -b dev
$ git branch  # 查看分支
$ vim code.txt 
$ git add code.txt 
$ git commit -m 'dev分支提交2'
$ git log --pretty=oneline

2.切换回master,并修改文件code.txt

$ git checkout master 
$ vim code.txt
$ git add code.txt 
$ git commit -m 'master分支提交'
$ git log --pretty=oneline

3.合并dev分支到master,能看下面自动合并错误,产生了合并冲突merge confict

$ git merge dev
Auto-merging code.txt
CONFLICT (content): Merge conflict in code.txt
Automatic merge failed; fix conflicts and then commit the result.

4.上面已经提示了冲突文件,当然也可以使用命令查看冲突文件:

$ git status  # 会显示出冲突的文件
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:   code.txt

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

5.解决冲突,删除git给标识出来的冲突内容,手动融合

$ vim code.txt  # 打开冲突文件
# 冲突内容会用下面的标识
<<<<<<< HEAD
=======
>>>>>>> dev
$ git add code.txt  # 解决冲突后,提交一下
$ git commit -m '解决分支合并冲突'
$ git log --pretty=oneline

6.查看分支合并记录:

$ git log --graph
$ git log --graph --pretty=oneline

7.最后可以删除dev分支即可

$ git branch -d dev
$ git branch 

5.4 分支管理策略

通常,合并分支时,如果可能,git会用Fast-forward模式,但是有些快速合并不能成功并且没有冲突,这个时候git会合并之后并做一次新的提交!!这种模式下,删除分支后,会丢掉分支信息!!

1.创建切换到dev分支下

$ git checkout -b dev
$ git branch

2.新建一个文件code3.txt,编辑内容,并做一个commit

$ vim code3.txt
$ ls
$ git add code3.txt
$ git commit -m '创建文件code3.txt'
$ git log --pretty=oneline

3.切换到master分支,编辑code.txt并进行一个提交

$ git checkout master
$ git log --pretty=oneline
$ vim code.txt
$ git add code.txt
$ git commit -m '添加新行'
$ git log --pretty=oneline

4.合并dev分支的内容到master分支,出现下面的提示

$ git merge dev
此时会有和输入弹框,用来说明合并分支的信息,如果提交空说明会终止提交,键盘I开始输入,esc输入完毕,进入命令模式,输入:wq即可退出,git会自动帮提交commit
$ git log --pretty=oneline

附带输入完毕退出之后的git提交信息:发现它的策略是:recursive strategy

$ git merge dev
Merge made by the 'recursive' strategy.
 code3.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 code3.txt

5.先查看提交记录,带分支合并图,删除dev分支

$ git log --graph --pretty=oneline
$ git branch -d dev

如果要强制禁用Fast-forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息

1.创建并切换到dev分支

$ git checkout -b dev

2.修改code.txt内容,并提交一个commit

$ vim code.txt
$ git add code.txt
$ git commit -m 'dev添加新行'

3.切换到master分支

$ git checkout master

4.合并dev分支到master分支,禁止使用fast-forward模式,注意参数--no-ff -m

$ git merge --no-ff -m '禁用fast-forward合并' dev
Merge made by the 'recursive' strategy.
 code.txt | 1 +
 1 file changed, 1 insertion(+)

-m参数把合并信息填写进去,git会自动加到commit信息

5.合并后,查看分支历史,可以看到,不使用fast-forward模式,就会能在历史记录中看到合并记录

$ git log --pretty=oneline --graph 

6.最后可以删除dev分支即可

$ git branch -d dev
$ git branch 

5.5 bug分支

软件开发中,bug很多,需要修改,在git中,由于分支是如此强大,所以每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支闪出去。

1.当你接到一个修复代号为001的bug任务,很自然地,你想创建一个分支bug-001来修复它,但是,等等,当前正在dev上进行的工作还没有提及:

$ git checkout -b dev
$ vim code3.txt
$ git status
On branch dev
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:   code3.txt

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

并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需要1天时间,但是必须在两个小时内修改bug,怎么办呀?

2.Git还提供一个stash功能,可以把当前工作现场储藏起来,等以后恢复现场后,继续工作

$ git stash
Saved working directory and index state WIP on dev: 265f7f3 禁用fast-forward合并
$ git status
On branch dev
nothing to commit, working tree clean

3.首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master上创建临时分支

$ git checkout master
$ git checkout -b bug-001
$ git branch

4.现在修改bug,比如删掉文件code.txt内的一行文本

$ ls
$ vim code.txt
$ git add code.txt
$ git commit -m '修复001bug'

5.修改完成后,回到master分支,并完成合并,最后删除bug-001分支

$ git checkout master 
# 注意,为了保留bug分支合并记录,没使用`fast-forward`模式
$ git merge --no-ff -m '修复bug001' bug-001 
$ git branch -d bug-001
$ git branch
$ git log --pretty=oneline --graph 

6.现在bug-001修复完成,是时候回到dev分支继续干活了

$ git checkout dev
$ git status
On branch dev
nothing to commit, working tree clean

7.工作区是干净的,刚刚的工作现场存哪去了?使用命令查看一下:

$ git stash list
stash@{0}: WIP on dev: 265f7f3 禁用fast-forward合并

工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下.

$ git stash pop  # 恢复工作现场
On branch dev
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:   code3.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (83885218b343475028379e6c095226be86e2f816)
$ git status  # 发现已回到之前的工作代码状态

小结:
修改bug时,我们会通过新建bug分支进行修复,然后合并,最后删除。
当手头工作没有完成时,先把工作现场git stash一下,然后去修bug。修复完成后,再git stash pop回到工作现场。

5.6 本章总结

  • 分支操作的基本命令
  • 查看分支git branch
  • 创建分支git branch 分支名
  • 切换分支git checkout 分支名
  • 创建并切换分支git checkout -b 分支名
  • 合并分支git merge 分支名
  • 删除分支git branch -d 分支名
  • 分支冲突
  • 两个分支都有新的提交记录,并且修改是同一个文件
  • 手动融合冲突内容<<<<<<<,=======,>>>>>>>
  • 分支管理策略
  • 合并的时候,如果可以,执行快速合并fast-forward
  • 禁止快速合并git merge --no-ff -m '提交内容' 分支名
  • bug分支
  • 存储工作现场git stash
  • 切换到bug所在分支,并创建一个临时分支,完成修复,合并分支
  • 回到工作现场git stash pop

6.远程相关

6.1 创建仓库

这里不同的Git平台不太一样,自行查即可。比如Github,码云

6.2 添加SSH账户

SSH的简单实用

6.3 克隆项目

看到克隆地址,一般是两种方式:SSHHttps

$ cd xx  # cd到合适的目录
$ git clone 仓库地址

6.4 推送分支

1.项目克隆到本地之后,执行下面命令创建分支dev

$ git checkout -b dev
$ git branch

2.创建一个文件,并提交一个版本

$ vim view.py
$ ls
$ git add *
$ git commit -m '创建index视图'

3.推送到远程服务器:推送分支就是把该分支上的所有本地提交推送到远程库,推送时要指定本地分支,这样,git就会把该分支推送到远程库对应的分支上

$ git push origin 分支名  # origin 代表远程库
# 例如
$ git push origin dev

6.5 跟踪远程分支

将本地分支跟踪服务器分支

$ git branch --set--upstream-to=origin/远程分支名 本地分支名
# 例如
$ git branch --set-upstream-to=origin/dev dev

主要是为了分支代码的同步,让远程分支或者本地分支有新版本时,能及时拉取和同步,比如本地更改以后,提交到远程分支

$ vim view.py
$ git add view.py
$ git commit -m '提交新内容'
$ git status  # 会提示本地分支领先远程分支
$ git push  # 推送到远程

6.6 从远程分支拉取代码

当别人提交了代码到远程分支上,拉取代码

$ git pull origin 远程分支名
# 例如
$ git pull origin dev

使用上面命令会把远程分支dev上的代码下载合并到本地所在分支。

7.高频命令

如下所示:

# 查看所有远程分支
$ git branch -r
# 创建一个本地分支dev, 并切换到该分支
$ git checkout -b dev
# 切换到名字为origin/test的远程分支
$ git checkout --track origin/test
# 创建一个名字为dev的本地分支, 并将该本地分支跟踪到名字为origin/test的远程分支
$ git checkout -b dev --track origin/test

Git的gitignore文件不生效办法

$ git rm -r --cached .
$ git add .
$ git commit -m 'update .gitignore'

Git强制分支覆盖Maser分支
假设分支test覆盖到Master.方法一:

# 将test分支强制(-f)推送到主分支master
$ git push origin test:master -f

方法二: (假设当前位于test分支)

$ git checkout master  # 将当前分支切换到主分支
$ git reset --hard test  # 将主分支重置为test分支
$ git push origin master -f  # 将重置后的master分支强制推送到远程仓库

Git回滚某个版本并同步到远程

$ git reset --hard xxxx   # xxx是git版本号
$ git push origin master -f  # 强制提交到远程

如果你在远端已经建立过分支,本地创建并跟踪这个远程分支

# devName是本地分支  origin/devName是远端分支
$ git checkout -b devName origin/devName

从某一个commit开始创建本地分支

git checkout commitId -b 本地branchName

# 推送到远程,远程此时还没有这个分支的情况下
git push origin 本地branchName

提交本地代码到新分支
背景:从branchA分支拉了一份代码,做了一些修改,但是不想提交到branchA分支,想新建一个分支branchB保存代码。

$ git add .
$ git commit -m "update"
$ git push origin branchA:branchB
# 仓库中原本没有branchB,提交后会生成新分支branchB,并将本地基于branchA修改的代码提交到branchB中.

# 切换到新分支
$ git checkout -b branchB origin/branchB

但是上面的操作会让branchA多一条commit,可以回退一下即可git reset --hard commit_id

移除本地所有未跟踪的文件

$ git clean -xfd
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容

  • 1. 安装和初始化设置 git config --global name "your name"git confi...
    午觉不眠Orz阅读 360评论 0 0
  • 前言 Git在平时的开发中经常使用,整理Git使用全面的梳理。 基本内容 开始之前 请自行准备好Git工具以及配置...
    weir_will阅读 239评论 0 1
  • 1、git将文件添加到.gitignore文件中不生效? 原因:在加入.gitignore前该文件已经被追踪。gi...
    疯狂艺人阅读 238评论 0 0
  • 初始化仓库 配置用户目录下.gitconfig .gitconfig 创建仓库 创建仓库 添加文件到仓库 新建文件...
    zhaoolee阅读 642评论 2 16
  • 初始化git . git init 初始化一个git resposity git add 添加到暂存区(红色表...
    maskwang520阅读 505评论 0 2