git 常用命令

命令含义
配置git config配置
git status查看状态
git log查看提交日志
基础命令git init初始化仓库
git add将工作区修改提交到暂存区(工作区 -> 暂存区)
git commit将暂存区修改提交到本地版本库(暂存区 -> 本地版本库)
git checkout – file丢弃工作区的修改
git reset HEAD file丢弃暂存区的修改
git rm删除文件,并提交到暂存区
git mv重命名文件,并提交到暂存区
git blamegit blame 查看文件的每个部分是谁修改的, 只要运行’git blame [filename]’, 你就会得到整个文件的每一行的详细修改信息:包括SHA串,日期和作者
分支命令git branch查看本地分支,查看所有分支: git branch -a,查看远程分支:git branch -r
git branch branch-name创建分支
git checkout -b branch-name创建并切换到分支
git checkout branch-name切换分支
git branch -d branch-name删除分支,有修改未合并无法删除。强制删除用-D参数:git branch -D branch-name
git merge合并分支,Fast-forward/冲突
git reset –hard HEAD^回退到上一个版本,^^回退前两个版本,以此类推
git reset –hard HEAD~n回退到前n个版本
git reset –hard commit_id回到某个版本
git reflog查看操作日志
远程命令git push将本地代码推送到远程仓库,完整命令:git push origin src:dst
git pull从远程仓库拉取代码到本地,等价于git fetch + git checkout。git fetch 是从远程版本库到本地版本库。
git clone克隆远程仓库的代码
git remote show本地工程对应的所有远程仓库
git push origin –delete删除远程分支

git基础

官方指导:
https://git-scm.com/book/en/v2

学习网站:

1. 概念

Git是一款免费、开源的分布式版本控制系统。

维基百科定义:https://en.wikipedia.org/wiki/Git

2. 安装(mac)

2.1 下载

到官网 https://git-scm.com/ 下载dmg包,我下载的是2.14.1版本

git-2.14.1-intel-universal-mavericks.dmg

2.2 安装

双击安装,按提示下一步就可以,安装完成后在终端输入:

git –version

如果显示出版本号,即安装成功。

➜  ~ git --version
git version 2.14.1

3. 配置

git 配置使用命令 git config

3.1 配置帮助

git config 有很多参数,具体参数可以查看帮助文档,查看方式有如下三种:

  • git config –help
  • git help config
  • man git-config
3.2 配置用户名和邮箱

使用git前一般需要配置用户名和邮箱,配置用户名和邮箱有三个参数,不同的参数作用范围不一样:

三种方式优先级 local > global > system

参数作用范围对应修改的文件
–system针对整个系统,整个电脑的配置文件(不常用)/etc/gitconfig
–global针对当前用户配置文件(常用)~/.gitconfig
–local针对特定项目的配置文件(常用)项目根目录下 .git/config
➜  ~ git config --global user.name "懿名"
➜  ~ git config --global user.email "lilongjiu_lntu@163.com"

我们用的是 –global参数,所以查看一下~/.gitconfig文件

➜  ~ cat ~/.gitconfig 
[user]
    name = 懿名
    email = lilongjiu_lntu@163.com
➜  ~ 

用命令查看

➜  ~ git config --global --list

user.name=懿名
user.email=lilongjiu_lntu@163.com
➜  ~

4. 文件的四种位置:

文件的四种位置

git所管理的文件,有四种位置,分为别:

  1. 工作区(Workspace)
  2. 暂存区(Index / Stage)
  3. 本地版本库(Repository)
  4. 远程版本库(Remote)
4.1 工作区

就是我们平时创建、修改文件的地方

4.2 暂存区

项目根目录下.git目录下的index文件, 暂存区会记录文件的相关信息(文件名、大小、timestamp…),不保保存实际的文件, 通过id指向每个文件实体。

4.3 本地版本库

记录提交文件的所有版本和日志

4.4 远程版本库

项目团队成员共享的版本库,开发人员从远程版本库拉取(pull)或者提交(push)代码。

5. 基础命令

5.1 基础配置
命令含义
git config配置
git status查看状态
git log查看提交日志
5.2 基本命令
命令含义
git init初始化仓库
git add将工作区修改提交到暂存区(工作区 -> 暂存区)
git commit将暂存区修改提交到本地版本库(暂存区 -> 本地版本库)
git checkout – file丢弃工作区的修改
git reset HEAD file丢弃暂存区的修改
git rm删除文件,并提交到暂存区
git mv重命名文件,并提交到暂存区
git blamegit blame 查看文件的每个部分是谁修改的, 只要运行’git blame [filename]’, 你就会得到整个文件的每一行的详细修改信息:包括SHA串,日期和作者
git init

初始化git仓库,git的所有版本信息都存储在 .git目录下,而svn会在每个目录下都有一个 .svn目录。默认情况下创建并进入master分支中,可以看到有一个master提示,这是因为系统安装了oh my zsh

➜  myproject ls -al
total 0
drwxr-xr-x  2 lilongjiu  staff   68 10 10 09:09 .
drwxr-xr-x  5 lilongjiu  staff  170 10 10 09:09 ..
➜  myproject git init
Initialized empty Git repository in /Users/lilongjiu/02workspace/git/myproject/.git/
➜  myproject git:(master)
git status

查看当前版本库的状态,初始化仓库后,项目根目录会创建一个.git目录,这个目录里存储git版本的所有信息。我们在这里创建一个文件test.txt,然后查看状态,“Untracked files”表示文件在工作中区中还未被追中,如果系统安装了oh my zsh 会有个 ✗ 提示

➜  myproject git:(master) ls -al
total 0
drwxr-xr-x   3 lilongjiu  staff  102 10 10 09:10 .
drwxr-xr-x   5 lilongjiu  staff  170 10 10 09:09 ..
drwxr-xr-x  10 lilongjiu  staff  340 10 10 09:10 .git
➜  myproject git:(master) echo "hello git" > test.txt
➜  myproject git:(master) ✗ git status 
On branch master

No commits yet

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

    test.txt

nothing added to commit but untracked files present (use "git add" to track)
➜  myproject git:(master) ✗ 
git add

将工作区已修改的文件存储到暂存区中,添加到暂存区后状态为“Changes to be committed”,表示待提交

➜  myproject git:(master) ✗ git add test.txt 
➜  myproject git:(master) ✗ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   test.txt

➜  myproject git:(master) ✗
git commit

将暂存区的文件提交到版本库,git提交文件,必须输入提交日志,默认情况下会用vi打开,提示你输入提交日志,以 # 号开头的行不会被提交。

➜  myproject git:(master) ✗ git commit test.txt

默认会用vi打开如下信息:
  1                                                                                                                                        
  2 # Please enter the commit message for your changes. Lines starting
  3 # with '#' will be ignored, and an empty message aborts the commit.
  4 #
  5 # On branch master
  6 #
  7 # Initial commit
  8 #
  9 # Changes to be committed:
 10 #   new file:   test.txt
 11 #

一般会在提交时直接输入提交日志,使用 -m 参数,这样就不会打开vi了。

➜  myproject git:(master) ✗ git commit -m "initial commit" test.txt
[master (root-commit) 5a8a23b] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt
➜  myproject git:(master)

文件提交后,可以看到 ✗ 已经没有了,表示没有待提交的文件了,可以通过git status证实这一点

➜  myproject git:(master) git status 
On branch master
nothing to commit, working tree clean
➜  myproject git:(master) 
git checkout – file

丢弃对工作区文件的修改

首先修改一下文件,增加一行,现在文件状态为未暂存”Changes not staged for commit”,也就是工作区的文件修改未提交到暂存区

➜  myproject git:(master) cat test.txt 
hello git
➜  myproject git:(master) echo "add a new line" >> test.txt 
➜  myproject git:(master) ✗ cat test.txt 
hello git
add a new line
➜  myproject git:(master) ✗ 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:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
➜  myproject git:(master) ✗ 

使用 git checkout – file 放弃工作区文件的修改(use “git checkout – …” to discard changes in working directory),可以看到新增加的一行被丢弃掉,同时可以看到 ✗ 已经变没了。

myproject git:(master)git checkout -- test.txtmyproject git:(master) git status
On branch master
nothing to commit, working tree cleanmyproject git:(master) cat test.txt 
hello gitmyproject git:(master) 
git reset HEAD file

丢弃暂存区的修改

HEAD 文件是一个指向你当前所在分支的引用标识符,它可以指向任意提交点。一般,你现在哪儿,HEAD 就指向哪儿(记录在.git/HEAD文件中)。

➜  myproject git:(master) cat .git/HEAD 
ref: refs/heads/master
➜  myproject git:(master) 

首先修改一下文件,增加一行,然后将工作区的修改提交到暂存区,状态为待提交(Changes to be committed)

➜  myproject git:(master) echo "add a new line" >> test.txt 
➜  myproject git:(master) ✗ git add test.txt 
➜  myproject git:(master) ✗ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   test.txt

➜  myproject git:(master) ✗ 

使用git reset HEAD丢弃暂存区的修改(use “git reset HEAD …” to unstage),文件状态变为待暂存(Changes not staged for commit)

➜  myproject git:(master) ✗ git reset HEAD test.txt 
Unstaged changes after reset:
M   test.txt
➜  myproject git:(master) ✗ 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:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")
➜  myproject git:(master) ✗ 
git rm

首先创建一个测试文件test2.txt,然后暂存,提交。git commit 提交到版本库会打开vi编辑器,让用户输入提交日志,可以使用 -m 参数,直接输入提交日志,而不必打开vi编辑器。

➜  myproject git:(master) ll
total 8
-rw-r--r--  1 lilongjiu  staff    10B 10 10 10:11 test.txt
➜  myproject git:(master) echo "test difference between git rm and rm" > test2.txt
➜  myproject git:(master) ✗ git add test2.txt
➜  myproject git:(master) ✗ git commit -m "add a new file test2.txt" test2.txt

[master ebf7ed3] add a new file test2.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test2.txt
➜  myproject git:(master) ll
total 16
-rw-r--r--  1 lilongjiu  staff    10B 10 10 10:11 test.txt
-rw-r--r--  1 lilongjiu  staff    38B 10 10 10:12 test2.txt
➜  myproject git:(master) 

使用 git rm 删除 test2.txt,可以看到工作区文件test2.txt被删除,并且文件状态为待提交,也就是文件删除已经被纳入到暂存区

➜  myproject git:(master) git rm test2.txt 
rm 'test2.txt'
➜  myproject git:(master) ✗ ll  
total 8
-rw-r--r--  1 lilongjiu  staff    10B 10 10 10:11 test.txt
➜  myproject git:(master) ✗ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    test2.txt

➜  myproject git:(master) ✗ 

假如是误删除,可以通过两步恢复,丢弃暂存区的修改,丢弃工作区的修改

myproject git:(master)git reset HEAD test2.txt
Unstaged changes after reset:
D   test2.txtmyproject git:(master)git checkout -- test2.txtmyproject git:(master) git status
On branch master
nothing to commit, working tree cleanmyproject git:(master) ll
total 16
-rw-r--r--  1 lilongjiu  staff    10B 10 10 10:11 test.txt
-rw-r--r--  1 lilongjiu  staff    38B 10 10 10:15 test2.txtmyproject git:(master) 

也可以使用操作系统 rm 删除命令删除test2.txt,可以看到工作区文件test2.txt被删除,然而文件并未被暂存,也就是只有工作区有修改

➜  myproject git:(master) rm test2.txt
➜  myproject git:(master) ✗ ll
total 8
-rw-r--r--  1 lilongjiu  staff    10B 10 10 10:11 test.txt
➜  myproject git:(master) ✗ 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:    test2.txt

no changes added to commit (use "git add" and/or "git commit -a")
➜  myproject git:(master) ✗ 

如果要恢复删除,通过一步就可以

myproject git:(master)git checkout -- test2.txtmyproject git:(master) ll
total 16
-rw-r--r--  1 lilongjiu  staff    10B 10 10 10:11 test.txt
-rw-r--r--  1 lilongjiu  staff    38B 10 10 10:16 test2.txtmyproject git:(master) git status
On branch master
nothing to commit, working tree cleanmyproject git:(master) 

综合以上对比,可以看到 git rm 与 rm 的区别

  • git rm: 两步动作,删除工作区文件,将删除动作提交到暂存区
  • rm: 一步动作,仅仅删除工作区的文件
git mv

重命名文件

git mv 与 mv 和 git rm 和 rm 原理一样

  • git mv: 两步动作,重命名工作区文件,将重命名动作提交到暂存区
  • mv: 一步动作,仅仅重命名工作区的文件
git commit –amend

修正上一次提交日志

git commit –amend -m “modify commit log”

myproject git:(master) git commit --amend -m "modify commit log"
[master 1ab72ee] modify commit log
 Date: Tue Oct 10 10:13:14 2017 +0800
 1 file changed, 1 insertion(+)
 create mode 100644 test2.txtmyproject git:(master)
git log

查看提交日志

➜  myproject git:(master) git log

commit 1ab72ee6e5c936b2a9b3723eeef79d8877b9984e (HEAD -> master)
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Tue Oct 10 10:13:14 2017 +0800

    modify commit log

commit ffc9cd2c42489a2c928648ae3432434406ffa119
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Tue Oct 10 10:12:01 2017 +0800

    delete test2.txt

commit 9bec42be1ef56f3ded52cc9dcb8ac62bf8e4b7bc
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Tue Oct 10 09:56:56 2017 +0800

    add a new file test2.txt

commit 5a8a23b89c003461364b5360ae86398a655b706b
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Tue Oct 10 09:21:33 2017 +0800

    initial commit
git log -n

查看最新的n条提交日志

➜  myproject git:(master) git log -1

commit 1ab72ee6e5c936b2a9b3723eeef79d8877b9984e (HEAD -> master)
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Tue Oct 10 10:13:14 2017 +0800

    modify commit log
(END)
git log –pretty=oneline

以一行的形式显示日志

➜  myproject git:(master) git log --pretty=oneline 

1ab72ee6e5c936b2a9b3723eeef79d8877b9984e (HEAD -> master) modify commit log
ffc9cd2c42489a2c928648ae3432434406ffa119 delete test2.txt
9bec42be1ef56f3ded52cc9dcb8ac62bf8e4b7bc add a new file test2.txt
5a8a23b89c003461364b5360ae86398a655b706b initial commit
git log –graph

以图形化的方式显示log

git blame

查看文件的每个部分是谁修改的,包括文件的每一行的详细修改信息:包括SHA串,日期和作者

myproject git:(master) git blame test.txt

^5a8a23b (懿名 2017-10-10 09:21:33 +0800 1) hello git

git blame 还可以使用 -L参数指定开始行和结束行

myproject git:(master) git blame -L 2,+2 test.txt

^5a8a23b (懿名 2017-10-10 09:21:33 +0800 1) hello git

6. .gitignore

并不是所有的项目文件都需要提交到版本库,比如说java的class文件或者ide生成的一些与项目代码无关的文件,是不需要提交到版本库中的。

首先创建一个文件test3.txt,新建文件状态为未追中

➜  myproject git:(master) echo "hello world" > test3.txt
➜  myproject git:(master) ✗ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    test3.txt

nothing added to commit but untracked files present (use "git add" to track)
➜  myproject git:(master) ✗ 

创建一个.gitignore文件,内容为test3.txt,然后提交到版本库

➜  myproject git:(master) ✗ echo "test3.txt" > .gitignore
➜  myproject git:(master) ✗ git add .gitignore
➜  myproject git:(master) ✗ git commit -m "add .gitignore file" .gitignore
[master a13927e] add .gitignore file
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
➜  myproject git:(master) 

可以看到我们没有把test3提交到版本库,但是git仓库是干净的,没有待提交的文件。

➜  myproject git:(master) git status          
On branch master
nothing to commit, working tree clean
➜  myproject git:(master) 

.gitignore 支持通配符,具体可以查看帮助文档:

➜  myproject git:(master) git help gitignore

7. git分支

git init 会创建一个master分支

命令含义
git branch查看本地分支,查看所有分支: git branch -a,查看远程分支:git branch -r
git branch branch-name创建分支
git checkout -b branch-name创建并切换到分支
git checkout branch-name切换分支
git branch -d branch-name删除分支,有修改未合并无法删除。强制删除用-D参数:git branch -D branch-name
git merge合并分支,Fast-forward/冲突
git reset –hard HEAD^回退到上一个版本,^^回退前两个版本,以此类推
git reset –hard HEAD~n回退到前n个版本
git reset –hard commit_id回到某个版本
git reflog查看操作日志
git branch

查看所有本地分支,当前只有master分支

myproject git:(master) git branch
* mastermyproject git:(master) 
git branch branch-name

创建新的分支develop

myproject git:(master) git branch developmyproject git:(master) git branch
  develop
* mastermyproject git:(master) 
git checkout branch-name

切换分支,从master切换到develop

➜  myproject git:(master) git checkout develop
Switched to branch 'develop'
➜  myproject git:(develop) git branch
* develop
  master
➜  myproject git:(develop) 
git checkout -b branch-name

创建并切换到分支,创建分支bugfix,然后切换到bugfix,一步到位

➜  myproject git:(develop) git checkout -b bugfix
Switched to a new branch 'bugfix'
➜  myproject git:(bugfix) git branch
* bugfix
  develop
  master
➜  myproject git:(bugfix) 
git branch -d branch-name

删除分支,第一次删不掉是因为,当前就在bugfix上,所以先切换到master,然后在删除bugfix分支

➜  myproject git:(bugfix) git branch -d bugfix
error: Cannot delete branch 'bugfix' checked out at '/Users/workspace/git/myproject'
➜  myproject git:(bugfix) git checkout master 
Switched to branch 'master'
➜  myproject git:(master) git branch -d bugfix
Deleted branch bugfix (was a13927e).
➜  myproject git:(master) 
git merge branch-name

合并分支

  • 直接合并

develop分支是从master分支创建来的,内容是一模一样的。现在develop分支test.txt增加一行。

➜  myproject git:(master) git checkout develop 
Switched to branch 'develop'
➜  myproject git:(develop) echo "add a new line in test.txt on branch develop" > test.txt
➜  myproject git:(develop) ✗ git commit -m "add a new line in test.txt on branch develop" test.txt
[develop e87fcd3] add a new line in test.txt on branch develop
 1 file changed, 1 insertion(+), 1 deletion(-)
➜  myproject git:(develop) 

由于develop分支是在master分支上增加了一行,所以可以直接把develop分支合并到master分支上,这种方式叫做 Fast-forward

➜  myproject git:(develop) git checkout master 
Switched to branch 'master'
➜  myproject git:(master) git merge develop 
Updating a13927e..e87fcd3
Fast-forward
 test.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
➜  myproject git:(master) 
  • 冲突合并

现在分别修改master和develop的test.txt

➜  myproject git:(master) echo "modify master" > test.txt
➜  myproject git:(master) ✗ git commit -m "modify master" test.txt 
[master 5273ae4] modify master
 1 file changed, 1 insertion(+), 1 deletion(-)

➜  myproject git:(master) git checkout develop 
Switched to branch 'develop'

➜  myproject git:(develop) echo "modify develop" > test.txt      
➜  myproject git:(develop) ✗ git commit -m "modify develop" test.txt
[develop 2bbdd7e] modify develop
 1 file changed, 1 insertion(+), 1 deletion(-)
➜  myproject git:(develop) 

由于master和develop分支都做过修改,所以合并会产生冲突,这就需要人工进行冲突合并

➜  myproject git:(develop) git checkout master 
Switched to branch 'master'
➜  myproject git:(master) git merge develop 
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
➜  myproject git:(master) ✗ 

用vi打开test.txt

 1 <<<<<<< HEAD                                                                                                                                                            
 2 modify master
 3 =======
 4 modify develop
 5 >>>>>>> develop

然后保留需要的修改,保存如下:

myproject git:(master)cat test.txt
modify developmyproject git:(master)

最后提交结果,这里的git add 表示的是标记冲突解决(mark resolution)

myproject git:(master)git add test.txtmyproject git:(master)git commit -m "fix conflict"
[master f20b818] fix conflictmyproject git:(master) 
git reset

版本回退

当前日志如下:

➜  myproject git:(master) git log --pretty=oneline
f20b818a309c09da4010f94944fc3d7af5bc3d79 (HEAD -> master) fix conflict
2bbdd7eaf94b16dde38b24ce27fb789df279b1df (develop) modify develop
5273ae468af097e39d2d10f2ce589e89f00de3fa modify master
e87fcd3c76c999aedc5f6b8418ecc7fa1b6f76be add a new line in test.txt on branch develop
a13927ee159a401ff834692fc04af17d261343db add .gitignore file
1ab72ee6e5c936b2a9b3723eeef79d8877b9984e modify commit log
ffc9cd2c42489a2c928648ae3432434406ffa119 delete test2.txt
9bec42be1ef56f3ded52cc9dcb8ac62bf8e4b7bc add a new file test2.txt
5a8a23b89c003461364b5360ae86398a655b706b initial commit
(END)
  • git reset –hard HEAD^

回退到上个版本,如果回退两个版本就用两个^^

➜  myproject git:(master) git reset --hard HEAD^
HEAD is now at 5273ae4 modify master
➜  myproject git:(master) 
➜  myproject git:(master) git log --pretty=oneline

5273ae468af097e39d2d10f2ce589e89f00de3fa (HEAD -> master) modify master
e87fcd3c76c999aedc5f6b8418ecc7fa1b6f76be add a new line in test.txt on branch develop
a13927ee159a401ff834692fc04af17d261343db add .gitignore file
1ab72ee6e5c936b2a9b3723eeef79d8877b9984e modify commit log
ffc9cd2c42489a2c928648ae3432434406ffa119 delete test2.txt
9bec42be1ef56f3ded52cc9dcb8ac62bf8e4b7bc add a new file test2.txt
5a8a23b89c003461364b5360ae86398a655b706b initial commit
(END)
  • git reset –hard HEAD~n

除了用^还可以用~n的方式,如果回退2个版本,就用git reset –hard HEAD~2

➜  myproject git:(master) git reset --hard HEAD~2 
HEAD is now at a13927e add .gitignore file
➜  myproject git:(master) 
➜  myproject git:(master) git log --pretty=oneline

a13927ee159a401ff834692fc04af17d261343db (HEAD -> master) add .gitignore file
1ab72ee6e5c936b2a9b3723eeef79d8877b9984e modify commit log
ffc9cd2c42489a2c928648ae3432434406ffa119 delete test2.txt
9bec42be1ef56f3ded52cc9dcb8ac62bf8e4b7bc add a new file test2.txt
5a8a23b89c003461364b5360ae86398a655b706b initial commit
(END)
  • git reset –hard commit_id

回退到任意一次提交id, commit_id 不需要全部写出,写前几位就够了,只要git能够区分出不同的提交id就可以。比如我们回退到初始提交(initial commit)版本5a8a23b89c003461364b5360ae86398a655b706b

➜  myproject git:(master) git reset --hard 5a8a2  
HEAD is now at 5a8a23b initial commit
➜  myproject git:(master) ✗
➜  myproject git:(master) ✗ git log --pretty=oneline

5a8a23b89c003461364b5360ae86398a655b706b (HEAD -> master) initial commit
(END)

回退到初始提交状态后出现了个 ✗ 是因为有文件未添加到版本库,之前没有出现是因为有.gitignore 文件,这次回退把.gitignore也回退了

  • git reflog

从最新的提交,回到历史版本,我们可以通过git log查看到历史的commit_id。但是如果从历史版本回到最新状态,我们是看不到最新的commit_id,git提供了另外一个命令git reflog,查询操作日志,当然也就可以查看所有的commit_id

➜  myproject git:(master) ✗ git reflog

5a8a23b (HEAD -> master) HEAD@{0}: reset: moving to 5a8a2
a13927e HEAD@{1}: reset: moving to HEAD~2
5273ae4 HEAD@{2}: reset: moving to HEAD^
f20b818 HEAD@{3}: commit (merge): fix conflict
5273ae4 HEAD@{4}: checkout: moving from develop to master
2bbdd7e (develop) HEAD@{5}: commit: modify develop
e87fcd3 HEAD@{6}: checkout: moving from master to develop
5273ae4 HEAD@{7}: commit: modify master
e87fcd3 HEAD@{8}: merge develop: Fast-forward
a13927e HEAD@{9}: checkout: moving from develop to master
e87fcd3 HEAD@{10}: commit: add a new line in test.txt on branch develop
a13927e HEAD@{11}: checkout: moving from master to develop
a13927e HEAD@{12}: checkout: moving from bugfix to master
a13927e HEAD@{13}: checkout: moving from develop to bugfix
a13927e HEAD@{14}: checkout: moving from master to develop
a13927e HEAD@{15}: commit: add .gitignore file
1ab72ee HEAD@{16}: commit (amend): modify commit log
669b5cb HEAD@{17}: commit (amend): add a new file test2.txt
ebf7ed3 HEAD@{18}: commit: add a new file test2.txt
ffc9cd2 HEAD@{19}: commit: delete test2.txt
9bec42b HEAD@{20}: commit: add a new file test2.txt
5a8a23b (HEAD -> master) HEAD@{21}: commit (initial): initial commit
(END)

8. git 远程操作

命令含义
git push将本地代码推送到远程仓库,完整命令:git push origin src:dst
git pull从远程仓库拉取代码到本地,等价于git fetch + git checkout。git fetch 是从远程版本库到本地版本库。
git clone克隆远程仓库的代码
git remote show本地工程对应的所有远程仓库
git push origin –delete删除远程分支



有时间补充。。。

9. 标签

git tag tag-name

创建标签

myproject git:(master) git tag v1.0myproject git:(master) 

创建标签并附加备注

➜  myproject git:(master) git tag -a v2.0 -m "version2.0 released"
➜  myproject git:(master) 
git tag

查看标签

myproject git:(master) git tag
v1.0
v2.0myproject git:(master) 
git tag -l

查找标签

➜  myproject git:(master) git tag -l 'v1*'
v1.0
➜  myproject git:(master) 
git tag -d

删除标签

➜  myproject git:(master) git tag -d v2.0 
Deleted tag 'v2.0' (was 5ebd0e6)
➜  myproject git:(master) git tag
v1.0
➜  myproject git:(master) 

10. 日志

git的提交日志是一个类似链表形式,根据下一次提交可以找到上一次提交

现在,初始化一个仓库,然后创建一个test.txt文件

➜  myproject git:(master) touch test.txt
➜  myproject git:(master) ✗ git add test.txt 
➜  myproject git:(master) ✗ git commit -m "initial commit" test.txt
[master (root-commit) 20ad634] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test.txt
➜  myproject git:(master) 

进行四次提交:

//第一次提交
➜  myproject git:(master) echo "first line" >> test.txt
➜  myproject git:(master) ✗ git commit -am "first commit"  
[master 4d735b0] first commit
 1 file changed, 1 insertion(+)
➜  myproject git:(master) 

//第二次提交
➜  myproject git:(master) echo "second line" >> test.txt
➜  myproject git:(master) ✗ git commit -am "second commit"
[master 7cf1e4b] second commit
 1 file changed, 1 insertion(+)
➜  myproject git:(master) 

//第三次提交
➜  myproject git:(master) echo "third line" >> test.txt
➜  myproject git:(master) ✗ 
➜  myproject git:(master) ✗ git commit -am "third commit" 
[master cbfab80] third commit
 1 file changed, 1 insertion(+)
➜  myproject git:(master)            

//第四次提交                 
➜  myproject git:(master) echo "fourth line" >> test.txt
➜  myproject git:(master) ✗ git commit -am "fourth commit"
[master 86e7fa4] fourth commit
 1 file changed, 1 insertion(+)
➜  myproject git:(master) 

现在test.txt内容和日志如下:

➜  myproject git:(master) cat test.txt 
first line
second line
third line
fourth line
➜  myproject git:(master)
➜  myproject git:(master) git log

commit 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d (HEAD -> master)
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Wed Oct 11 21:18:13 2017 +0800

    fourth commit

commit cbfab806941c47298c43ec1b86b6491e916a04f8
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Wed Oct 11 21:17:58 2017 +0800

    third commit

commit 7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Wed Oct 11 21:17:45 2017 +0800

    second commit

commit 4d735b09358b4e4d61124336789edfdf3802050b
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Wed Oct 11 21:17:31 2017 +0800

    first commit

commit 20ad634e11a6a49e47abad0a257f99ce73797bc7
Author: 懿名 <lilongjiu_lntu@163.com>
Date:   Wed Oct 11 21:17:04 2017 +0800

    initial commit

在.git/logs/refs/heads目录下存储着各个分支的日志信息

  myproject git:(master) ll .git/logs/refs/heads
total 16
-rw-r--r--  1 lilongjiu  staff   774B 10 11 21:18 master
  myproject git:(master)

在master分支下,可以看到每次提交的日志,并且每一次提交都记录了上一次提交的id。

➜  myproject git:(master) cat .git/logs/refs/heads/master 
0000000000000000000000000000000000000000 20ad634e11a6a49e47abad0a257f99ce73797bc7 懿名 <lilongjiu_lntu@163.com> 1507727824 +0800  commit (initial): initial commit
20ad634e11a6a49e47abad0a257f99ce73797bc7 4d735b09358b4e4d61124336789edfdf3802050b 懿名 <lilongjiu_lntu@163.com> 1507727851 +0800  commit: first commit
4d735b09358b4e4d61124336789edfdf3802050b 7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 懿名 <lilongjiu_lntu@163.com> 1507727865 +0800  commit: second commit
7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 cbfab806941c47298c43ec1b86b6491e916a04f8 懿名 <lilongjiu_lntu@163.com> 1507727878 +0800  commit: third commit
cbfab806941c47298c43ec1b86b6491e916a04f8 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 懿名 <lilongjiu_lntu@163.com> 1507727893 +0800  commit: fourth commit
➜  myproject git:(master) 

可以画个提交日志示意图:
这里写图片描述

顺便说一下,之前我们经常用的HEAD,其实就是一个指针(通过.git/HEAD查看),指向当前你所在的位置

➜  myproject git:(master) cat .git/HEAD 
ref: refs/heads/master
➜  myproject git:(master) 

也就是这个样子
这里写图片描述

现在,在这个基础上我们创建一个分支develop

myproject git:(master) git branch developmyproject git:(master) git branch
  develop
* mastermyproject git:(master) 

在 .git/logs/refs/heads会多出一个文件develop

  myproject git:(master) ll .git/logs/refs/heads
total 16
-rw-r--r--  1 lilongjiu  staff   159B 10 11 21:35 develop
-rw-r--r--  1 lilongjiu  staff   774B 10 11 21:18 master
  myproject git:(master) 

现在查看一下master和develop分支的日志

➜  myproject git:(master) cat .git/logs/refs/heads/master 
0000000000000000000000000000000000000000 20ad634e11a6a49e47abad0a257f99ce73797bc7 懿名 <lilongjiu_lntu@163.com> 1507727824 +0800  commit (initial): initial commit
20ad634e11a6a49e47abad0a257f99ce73797bc7 4d735b09358b4e4d61124336789edfdf3802050b 懿名 <lilongjiu_lntu@163.com> 1507727851 +0800  commit: first commit
4d735b09358b4e4d61124336789edfdf3802050b 7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 懿名 <lilongjiu_lntu@163.com> 1507727865 +0800  commit: second commit
7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 cbfab806941c47298c43ec1b86b6491e916a04f8 懿名 <lilongjiu_lntu@163.com> 1507727878 +0800  commit: third commit
cbfab806941c47298c43ec1b86b6491e916a04f8 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 懿名 <lilongjiu_lntu@163.com> 1507727893 +0800  commit: fourth commit
➜  myproject git:(master)                                
➜  myproject git:(master) cat .git/logs/refs/heads/develop
0000000000000000000000000000000000000000 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 懿名 <lilongjiu_lntu@163.com> 1507728910 +0800  branch: Created from master
➜  myproject git:(master) 

从下面的图,可以看到develop分支的提交id就是master最后一次提交的id,git创建分支是非常轻量级的,仅仅是创建一个指针。
这里写图片描述

现在我们切换到develop分支

➜  myproject git:(master) git checkout develop            
➜  myproject git:(develop) cat .git/HEAD 
ref: refs/heads/develop
➜  myproject git:(develop) 

可以看到HEAD指向了develop
这里写图片描述

我们在develop分支上做一次修改,提交,然后查看日志:

myproject git:(develop) echo "add by develop" >> test.txtmyproject git:(develop)git commit -am "commit by develop"
[develop 640b944] commit by develop
 1 file changed, 1 insertion(+)
➜  myproject git:(develop) 
➜  myproject git:(develop) cat .git/logs/refs/heads/master 
0000000000000000000000000000000000000000 20ad634e11a6a49e47abad0a257f99ce73797bc7 懿名 <lilongjiu_lntu@163.com> 1507727824 +0800  commit (initial): initial commit
20ad634e11a6a49e47abad0a257f99ce73797bc7 4d735b09358b4e4d61124336789edfdf3802050b 懿名 <lilongjiu_lntu@163.com> 1507727851 +0800  commit: first commit
4d735b09358b4e4d61124336789edfdf3802050b 7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 懿名 <lilongjiu_lntu@163.com> 1507727865 +0800  commit: second commit
7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 cbfab806941c47298c43ec1b86b6491e916a04f8 懿名 <lilongjiu_lntu@163.com> 1507727878 +0800  commit: third commit
cbfab806941c47298c43ec1b86b6491e916a04f8 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 懿名 <lilongjiu_lntu@163.com> 1507727893 +0800  commit: fourth commit
➜  myproject git:(develop) 

➜  myproject git:(develop) cat .git/logs/refs/heads/develop
0000000000000000000000000000000000000000 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 懿名 <lilongjiu_lntu@163.com> 1507728910 +0800  branch: Created from master
86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 640b9445b4ab2f3b10eb53b7a02b5c8c6dd1d105 懿名 <lilongjiu_lntu@163.com> 1507729967 +0800  commit: commit by develop
➜  myproject git:(develop) 

现在的提交示意图如下:
这里写图片描述

再次理解Fast-forward

在前面的基础下,将develop分支合并到master分支,那么根据之前的讲解,应该是Fast-forward

➜  myproject git:(develop) git checkout master
Switched to branch 'master'
➜  myproject git:(master) git merge develop 
Updating 86e7fa4..640b944
Fast-forward
 test.txt | 1 +
 1 file changed, 1 insertion(+)
➜  myproject git:(master) 

合并后,我们再看一下日志:

➜  myproject git:(master) cat .git/logs/refs/heads/master
0000000000000000000000000000000000000000 20ad634e11a6a49e47abad0a257f99ce73797bc7 懿名 <lilongjiu_lntu@163.com> 1507727824 +0800  commit (initial): initial commit
20ad634e11a6a49e47abad0a257f99ce73797bc7 4d735b09358b4e4d61124336789edfdf3802050b 懿名 <lilongjiu_lntu@163.com> 1507727851 +0800  commit: first commit
4d735b09358b4e4d61124336789edfdf3802050b 7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 懿名 <lilongjiu_lntu@163.com> 1507727865 +0800  commit: second commit
7cf1e4b7ac9b36724bcd5d906e48ac4abaca4c51 cbfab806941c47298c43ec1b86b6491e916a04f8 懿名 <lilongjiu_lntu@163.com> 1507727878 +0800  commit: third commit
cbfab806941c47298c43ec1b86b6491e916a04f8 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 懿名 <lilongjiu_lntu@163.com> 1507727893 +0800  commit: fourth commit
86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 640b9445b4ab2f3b10eb53b7a02b5c8c6dd1d105 懿名 <lilongjiu_lntu@163.com> 1507730283 +0800  merge develop: Fast-forward
➜  myproject git:(master) 
➜  myproject git:(master) cat .git/logs/refs/heads/develop 
0000000000000000000000000000000000000000 86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 懿名 <lilongjiu_lntu@163.com> 1507728910 +0800  branch: Created from master
86e7fa413ea7fa8a527daeaae3cdbf9309dd3d5d 640b9445b4ab2f3b10eb53b7a02b5c8c6dd1d105 懿名 <lilongjiu_lntu@163.com> 1507729967 +0800  commit: commit by develop
➜  myproject git:(master) 

从上面的的日志可以看到,master分支的最后一条提交id,就是develop分支的最后一次提交id,也就是说Fast-forward仅仅是指针的移动,图示如下:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值