Git学习笔记

初识git

git官网

作者简介

作者:林纳斯·托瓦兹(Linus Benedict Torvalds, 1969年~ ),著名的电脑程序员、黑客。Linux内核的发明人及该计划的合作者。托瓦兹利用个人时间及器材创造出了这套当今全球最流行的操作系统(作业系统)内核之一。(大学期间写出了Linux的内核)。

托瓦兹照片

版本管理的三个发展阶段

本地式

最早的版本管理模式,在一台电脑上作业,在本地有一个版本库,用来存放文件。

本地式版本管理
  • 优点:安全
  • 缺点:
    • 只能在单台电脑进行版本管理
    • 无法与多人协作

集中式

有一台服务器专门当作版本仓库,用于存放文件,

集中式
  • 优点:可以多人协作了
  • 缺点:
    • 如果网络不好,则无法进行版本管理
    • 如果本人不在局域网中也无法进行版本管理
    • 需要定期备份
    • 如果服务器挂掉,需要数据恢复才可以版本管理,当然如果没有定期备份,只能~~呵呵了

分布式

分布式

每个参与项目的人都会有一个完整的仓库信息,即使服务器挂掉,可以新起项目,上传文件,这个新项目有以前所有的版本信息,不影响大家作业,甚至可以在家作业,然后第二天将正确的版本跟新上传到的服务器。

补充:git和svn等存储方式的区别

区别

  • svn存储方式

  • git存储方式

因此,在使用svn的时候是在需要提交文件的上级目录管理此目录全部的文件。
但是,git是只要在此工程下,管理的都是该工程的文件,因此如果使用git在分支合并,git pull的时候一定要将本项目的文件commit才可以,要不然很容易会合并失败,甚至是冲突很多文件

git的诞生

有兴趣的可以自己查一下

使用git

初次运行git前的配置

  1. 查看git的帮助,提示git后面可选的操作

    git --help
    
  2. 查看git某种操作的帮助

    git clone -h
    git clone --help
    
  3. 初次运行git前的配置

    可以不用先不考虑,当需要的时候再去根据提示进行配置

    • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
    • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。
    • 当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig中的同名变量。

    在 Windows 系统上,Git 会找寻用户主目录下的 .gitconfig 文件。主目录即 USER。此外,Git 还会尝试找寻 /etc/gitconfig 文件,只不过看当初 Git 装在什么目录,就以此作为根目录来定位。

  4. 用户信息

    • 查看帮助

      git config  -h
      
    • 设置

      git config --global user.name "xxx"
      git config --global user.email "[email protected]"
      
  5. 文本编辑器

    可以考虑不设置

    git config --global core.editor emacs
    
  6. 差异分析工具

    git config --global merge.tool vimdiff
    
  7. 查看配置信息

    git config --list

    user.name=xxx
    [email protected]
    merge.tool=vimdiff
    
    color.status=auto
    color.branch=auto
    color.interactive=auto
    color.diff=auto
    ...
    
  8. 直接阅读变量

    git config user.name
    
  9. 获取帮助

    git help 
    git  --help
    man git-
    

创建第一个版本库和第一次提交

  1. 创建一个版本库

    [root@Jolay data]# git init demo
    Initialized empty Git repository in /data/demo/.git/
    [root@Jolay data]# ls
    demo
    [root@Jolay data]# ll -a demo/
    total 0
    drwxr-xr-x 3 root root  17 Nov  8 23:17 .
    drwxr-xr-x 3 root root  17 Nov  8 23:17 ..
    drwxr-xr-x 7 root root 111 Nov  8 23:17 .git
    

    此时:创建库成功

  2. 第一次提交

    git 几个区域的概念

    文件的变化状态

    先透露一个命令 git status:查看本地git仓库的状态

    追踪一个文件前,查看本地仓库的状态

    [root@Jolay data]# cd demo/
    [root@Jolay demo]# ls
    [root@Jolay demo]# touch a.txt
    [root@Jolay demo]# ls
    a.txt
    [root@Jolay demo]# git status
    # On branch master
    #
    # Initial commit
    #
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       a.txt
    nothing added to commit but untracked files present (use "git add" to track)
    

    追踪文件后,查看本地仓库的状态

    [root@Jolay demo]# ls
    a.txt
    [root@Jolay demo]# git add a.txt
    [root@Jolay demo]# git status
    # On branch master
    #
    # Initial commit
    #
    # Changes to be committed:
    #   (use "git rm --cached ..." to unstage)
    #
    #       new file:   a.txt
    #
    [root@Jolay demo]#
    

    提交一个文件后,查看本地仓库的状态

    [root@Jolay demo]# git commit -m "first commit"
    [master (root-commit) b7172f0] first commit
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 a.txt
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@Jolay demo]#  
    
  1. 第二次提交

    [root@Jolay demo]# ls
    a.txt
    [root@Jolay demo]# echo hello > a.txt 
    [root@Jolay demo]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add ..." to update what will be committed)
    #   (use "git checkout -- ..." to discard changes in working directory)
    #
    #       modified:   a.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@Jolay demo]# 
    [root@Jolay demo]# git add a.txt 
    [root@Jolay demo]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD ..." to unstage)
    #
    #       modified:   a.txt
    #
    [root@Jolay demo]# git commit -m "second commit"
    [master 02ddd86] second commit
     1 file changed, 1 insertion(+)
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@Jolay demo]# 
    
  2. 第三次提交

    [root@Jolay demo]# ls
    a.txt
    [root@Jolay demo]# touch b.txt c.txt
    [root@Jolay demo]# 
    [root@Jolay demo]# git status
    # On branch master
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       b.txt
    #       c.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@Jolay demo]# git add b.txt
    [root@Jolay demo]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD ..." to unstage)
    #
    #       new file:   b.txt
    #
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       c.txt
    [root@Jolay demo]# git commit -m "third commit"
    [master ab73ce8] third commit
     1 file changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 b.txt
    [root@Jolay demo]# git status
    # On branch master
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       c.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@Jolay demo]# 
    
    文件的变化状态

git的提交信息git commit

  1. 查看git的commit信息

    方式一:

    [root@Jolay demo]# git log
    commit 02ddd86425e4333ab72afe5b59b593d5a3eea9a4
    Author: xxx 
    Date:   Tue Nov 8 23:42:21 2016 +0800
    
        second commit
    
    commit b7172f012572a064fd057577250020528209e902
    Author: xxx 
    Date:   Tue Nov 8 23:27:31 2016 +0800
    
        first commit
    [root@Jolay demo]# 
    

    方式二:

    只有在初始化仓库,提交过一次过后才能使用(查看上一次提交信息)

    [root@Jolay demo]# git show
    commit 02ddd86425e4333ab72afe5b59b593d5a3eea9a4
    Author: xxx 
    Date:   Tue Nov 8 23:42:21 2016 +0800
    
        second commit
    
    diff --git a/a.txt b/a.txt
    index e69de29..ce01362 100644
    --- a/a.txt
    +++ b/a.txt
    @@ -0,0 +1 @@
    +hello
    [root@Jolay demo]#
    

git暂存区(追踪)git add

  1. 添加一个文件

    添加一个文件,并查看添加文件(追踪文件)后的状态,

    [root@Jolay demo]# ls
     a.txt  b.txt  c.txt
    [root@Jolay demo]# git status
    # On branch master
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       c.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@Jolay demo]# git add c.txt 
    [root@Jolay demo]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD ..." to unstage)
    #
    #       new file:   c.txt
    #
    [root@Jolay demo]# 
    
  2. 修改一个文件

    [root@Jolay demo]# echo "hello world" > c.txt
    [root@Jolay demo]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD ..." to unstage)
    #
    #       new file:   c.txt
    #
    # Changes not staged for commit:
    #   (use "git add ..." to update what will be committed)
    #   (use "git checkout -- ..." to discard changes in working directory)
    #
    #       modified:   c.txt
    #
    [root@Jolay demo]# 
    [root@Jolay demo]# git commit -m "test"
    [root@Jolay demo]# git status
    

文件的回滚

  1. 环境准备

    将所有的数据都提交

    [root@Jolay demo]# git add .
    [root@Jolay demo]# git commit -m "forth commit"
    [master d46cff7] forth commit
     1 file changed, 1 insertion(+)
     create mode 100644 c.txt
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@Jolay demo]# 
    
  2. 回滚未追踪的文件,比如新增文件

    此类文件,直接删除就好

    [root@Jolay demo]# touch d.txt
    [root@Jolay demo]# git status
    # On branch master
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       d.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@Jolay demo]# 
    
  3. 回滚新git add的文件

    方式一:如果是新加的文件,此方式回滚

    此处亲自操组一下,看提示
    1. 新加文件
    2. git status
    3. git add
    4. git status
    5. 回滚
    6. git status
    7. git add
    8. git status
    9. 修改文件
    10. git status
    11. 回滚文件
    
  4. 回滚git commit的文件
    实验环境

    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt  d.txt
    [root@Jolay demo]# git status
    # On branch master
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       d.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@Jolay demo]# git add .
    [root@Jolay demo]# git commit -m 'fifth commit'
    [master 2665767] fifth commit
     1 file changed, 1 insertion(+)
     create mode 100644 d.txt
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    
    [root@Jolay demo]# git show
    commit 2665767519ab995e56ca7a5758c3a799d14bdad8
    Author: xxx 
    Date:   Wed Nov 9 00:39:01 2016 +0800
    
        fifth commit
    
    diff --git a/d.txt b/d.txt
    new file mode 100644
    index 0000000..ce01362
    --- /dev/null
    +++ b/d.txt
    @@ -0,0 +1 @@
    +hello
    [root@Jolay demo]# 
    

    回滚操作

    [root@Jolay demo]# git add .
    [root@Jolay demo]# git commit -m 'fifth commit'
    [master 2665767] fifth commit
     1 file changed, 1 insertion(+)
     create mode 100644 d.txt
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    
    [root@Jolay demo]# git show
    commit 2665767519ab995e56ca7a5758c3a799d14bdad8
    Author: xxx 
    Date:   Wed Nov 9 00:39:01 2016 +0800
    
        fifth commit
    
    diff --git a/d.txt b/d.txt
    new file mode 100644
    index 0000000..ce01362
    --- /dev/null
    +++ b/d.txt
    @@ -0,0 +1 @@
    +hello
    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt  d.txt
    [root@Jolay demo]# git reset 2665767519ab995e56ca7a5758c3a799d14bdad8
    [root@Jolay demo]# git show 
    commit 2665767519ab995e56ca7a5758c3a799d14bdad8
    Author: xxx 
    Date:   Wed Nov 9 00:39:01 2016 +0800
    
        fifth commit
    
    diff --git a/d.txt b/d.txt
    new file mode 100644
    index 0000000..ce01362
    --- /dev/null
    +++ b/d.txt
    @@ -0,0 +1 @@
    +hello
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@Jolay demo]# git log
    commit 2665767519ab995e56ca7a5758c3a799d14bdad8
    Author: xxx 
    Date:   Wed Nov 9 00:39:01 2016 +0800
    
        fifth commit
    
    commit d46cff75ca3d775db42c31afdf1ebd4c1b04c2d2
    Author: xxx 
    Date:   Wed Nov 9 00:14:13 2016 +0800
    
        forth commit
    
    commit ab73ce8273017bad67ccb575ab82755dbedf103e
    Author: xxx 
    Date:   Tue Nov 8 23:51:49 2016 +0800
    
        third commit
    
    commit 02ddd86425e4333ab72afe5b59b593d5a3eea9a4
    Author: xxx 
    Date:   Tue Nov 8 23:42:21 2016 +0800
    
        second commit
    
    commit b7172f012572a064fd057577250020528209e902
    Author: xxx 
    Date:   Tue Nov 8 23:27:31 2016 +0800
    
        first commit
    [root@Jolay demo]# git reset d46cff75ca3d775db42c31afdf1ebd4c1b04c2d2
    [root@Jolay demo]# git status
    # On branch master
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       d.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@Jolay demo]# git show
    commit d46cff75ca3d775db42c31afdf1ebd4c1b04c2d2
    Author: xxx 
    Date:   Wed Nov 9 00:14:13 2016 +0800
    
        forth commit
    
    diff --git a/c.txt b/c.txt
    new file mode 100644
    index 0000000..3b18e51
    --- /dev/null
    +++ b/c.txt
    @@ -0,0 +1 @@
    +hello world
    [root@Jolay demo]# git log
    commit d46cff75ca3d775db42c31afdf1ebd4c1b04c2d2
    Author: xxx 
    Date:   Wed Nov 9 00:14:13 2016 +0800
    
        forth commit
    
    commit ab73ce8273017bad67ccb575ab82755dbedf103e
    Author: xxx 
    Date:   Tue Nov 8 23:51:49 2016 +0800
    
        third commit
    
    commit 02ddd86425e4333ab72afe5b59b593d5a3eea9a4
    Author: xxx 
    Date:   Tue Nov 8 23:42:21 2016 +0800
    
        second commit
    
    commit b7172f012572a064fd057577250020528209e902
    Author: xxx 
    Date:   Tue Nov 8 23:27:31 2016 +0800
    
        first commit
    [root@Jolay demo]# 
    
  5. 多次git commit之后想回滚到某一版本,同上

    回滚只是本地仓库的回滚,工作空间不会被修改,当需要覆盖时,使用git checkout 文件名

    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt  d.txt
    [root@Jolay demo]# git status
    # On branch master
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #       d.txt
    nothing added to commit but untracked files present (use "git add" to track)
    [root@Jolay demo]# git add .
    [root@Jolay demo]# git commit -m "fifth commit"
    [master 41aa3e1] fifth commit
     1 file changed, 1 insertion(+)
     create mode 100644 d.txt
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@Jolay demo]# echo world > d.txt 
    [root@Jolay demo]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add ..." to update what will be committed)
    #   (use "git checkout -- ..." to discard changes in working directory)
    #
    #       modified:   d.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@Jolay demo]# git add d.txt 
    [root@Jolay demo]# git commit -m "sixth commit"
    [master 0cc2a7d] sixth commit
     1 file changed, 1 insertion(+), 1 deletion(-)
    [root@Jolay demo]# git log
    commit 0cc2a7d9e61b2226f1a10c52e02a0ab9c2fe5a53
    Author: xxx 
    Date:   Wed Nov 9 00:47:30 2016 +0800
    
        sixth commit
    
    commit 41aa3e15902ea6fff8df3853ae98754ac050f65d
    Author: xxx 
    Date:   Wed Nov 9 00:46:52 2016 +0800
    
        fifth commit
    
    commit d46cff75ca3d775db42c31afdf1ebd4c1b04c2d2
    Author: xxx 
    Date:   Wed Nov 9 00:14:13 2016 +0800
    
        forth commit
    
    commit ab73ce8273017bad67ccb575ab82755dbedf103e
    Author: xxx 
    Date:   Tue Nov 8 23:51:49 2016 +0800
    
        third commit
    
    commit 02ddd86425e4333ab72afe5b59b593d5a3eea9a4
    Author: xxx 
    Date:   Tue Nov 8 23:42:21 2016 +0800
    
        second commit
    
    commit b7172f012572a064fd057577250020528209e902
    [root@Jolay demo]# git reset 41aa3e15902ea6fff8df3853ae98754ac050f65d
    Unstaged changes after reset:
    M       d.txt
    [root@Jolay demo]# git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add ..." to update what will be committed)
    #   (use "git checkout -- ..." to discard changes in working directory)
    #
    #       modified:   d.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@Jolay demo]# cat d.txt 
    world
    [root@Jolay demo]# git checkout d.txt    
    [root@Jolay demo]# cat d.txt 
    hello
    [root@Jolay demo]# 
    

    此时我们其实已经穿插了git commit,提交给了本地仓库

  6. 总结文件的状态变化

    理解比较复杂,可以根据git status提示操作。

    文件状态的变化

    文件的变化状态
  7. 移除被追踪的文件

    尽量不要用

    git rm 文件名

    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt  d.txt
    [root@Jolay demo]# git status
    # On branch master
    nothing to commit, working directory clean
    [root@Jolay demo]# git show
    commit 41aa3e15902ea6fff8df3853ae98754ac050f65d
    Author: xxx 
    Date:   Wed Nov 9 00:46:52 2016 +0800
    
        fifth commit
    
    diff --git a/d.txt b/d.txt
    new file mode 100644
    index 0000000..ce01362
    --- /dev/null
    +++ b/d.txt
    @@ -0,0 +1 @@
    +hello
    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt  d.txt
    [root@Jolay demo]# git rm d.txt 
    rm 'd.txt'
    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt
    [root@Jolay demo]# git show
    commit 41aa3e15902ea6fff8df3853ae98754ac050f65d
    Author: xxx 
    Date:   Wed Nov 9 00:46:52 2016 +0800
    
        fifth commit
    
    diff --git a/d.txt b/d.txt
    new file mode 100644
    index 0000000..ce01362
    --- /dev/null
    +++ b/d.txt
    @@ -0,0 +1 @@
    +hello
    [root@Jolay demo]# git commit -m "rm d.txt"
    [master a443dea] rm d.txt
     1 file changed, 1 deletion(-)
     delete mode 100644 d.txt
    [root@Jolay demo]# 
    
  8. 重命名文件名

    git mv a.txt e.txt
    
  9. 查看状态的另一种格式-s (--short)

    git status -s
    

    当修改文件。add之后,再次修改文件,就会出现连个M。表示提交到暂存区后,又进行了修改,直接commit提交,会提交暂存区的文件,后修改的不回提交。只有再次add的时候会将后修改的内容,添加到暂存区,然后在此提交,会完成提交 添加测试代码,快速回滚

    [xxx@ops-monitor demo4]$ git status -s
    MM a.txt
    [xxx@ops-monitor demo4]$ 
    

git查看提交历史git log

git reflog
  1. git log 有许多选项可以帮助你搜寻感兴趣的提交,接下来我们介绍些最常用的。
    我们常用 -p 选项展开显示每次提交的内容差异,用 -2 则仅显示最近的两次更新

    git log -p -2
    
  1. git log 新版本的参数--word-diff,单词的差分,而非行级别的差分

    git log -U1 --word-diff
    
  2. 另外,git log 还提供了许多摘要选项可以用,比如 --stat,仅显示简要的增改行数统计:

    git log --stat
    
  1. 每个提交都列出了修改过的文件,以及其中添加和移除的行数,并在最后列出所有增减行数小计。 还有个常用的 --pretty 选项,可以指定使用完全不同于默认格式的方式展示提交历史。比如用 oneline 将每个提交放在一行显示,这在提交数很大时非常有用。另外还有 short,full 和 fuller 可以用,展示的信息或多或少有些不同,请自己动手实践一下看看效果如何。

    git log --pretty=oneline
    

    但最有意思的是 format,可以定制要显示的记录格式,这样的输出便于后期编程提取分析,像这样:

    git log --pretty=format:"%h - %an, %ar : %s"
    

    表 2-1 列出了常用的格式占位符写法及其代表的意义。

    选项 说明
    %H 提交对象(commit)的完整哈希字串
    %h 提交对象的简短哈希字串
    %T 树对象(tree)的完整哈希字串
    %t 树对象的简短哈希字串
    %P 父对象(parent)的完整哈希字串
    %p 父对象的简短哈希字串
    %an 作者(author)的名字
    %ae 作者的电子邮件地址
    %ad 作者修订日期(可以用 -date= 选项定制格式)
    %ar 作者修订日期,按多久以前的方式显示
    %cn 提交者(committer)的名字
    %ce 提交者的电子邮件地址
    %cd 提交日期
    %cr 提交日期,按多久以前的方式显示
    %s 提交说明

你一定奇怪作者(author)和提交者(committer)之间究竟有何差别,其实作者指的是实际作出修改的人,提交者指的是最后将此工作成果提交到仓库的人。所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。我们会在第五章再详细介绍两者之间的细微差别。

用 oneline 或 format 时结合 --graph 选项,可以看到开头多出一些 ASCII 字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况。在我们之前提到的 Grit 项目仓库中可以看到:

git log --pretty=format:"%h %s" --graph
  1. 参数说明

    选项 说明
    -p 按补丁格式显示每个更新之间的差异。
    --word-diff 按 word diff 格式显示差异。
    --stat 显示每次更新的文件修改统计信息。
    --shortstat 只显示 --stat 中最后的行数修改添加移除统计。
    --name-only 仅在提交信息后显示已修改的文件清单。
    --name-status 显示新增、修改、删除的文件清单。
    --abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
    --relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
    --graph 显示 ASCII 图形表示的分支合并历史。
    --pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)
    --oneline --pretty=oneline --abbrev-commit 的简化用法

    用 oneline 或 format 时结合 --graph 选项,可以看到开头多出一些 ASCII 字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况。在我们之前提到的 Grit 项目仓库中可以看到:

  2. 另外还有按照时间作限制的选项,比如 --since 和 --until。下面的命令列出所有最近两周内的提交:

    git log --since=2.weeks
    

    你可以给出各种时间格式,比如说具体的某一天(“2008-01-15”),或者是多久以前(“2 years 1 day 3 minutes ago”)

  3. 另一个真正实用的git log选项是路径(path),如果只关心某些文件或者目录的历史提交,可以在 git log 选项的最后指定它们的路径。因为是放在最后位置上的选项,所以用两个短划线(--)隔开之前的选项和后面限定的路径名。

    选项 说明
    -(n) 仅显示最近的 n 条提交
    --since, --after 仅显示指定时间之后的提交。
    --until, --before 仅显示指定时间之前的提交。
    --author 仅显示指定作者相关的提交。
    --committer 仅显示指定提交者相关的提交。

    来看一个实际的例子,如果要查看 Git 仓库中,2008 年 10 月期间,Junio Hamano 提交的但未合并的测试脚本(位于项目的 t/ 目录下的文件),可以用下面的查询命令:

    $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" --before="2008-11-01" --no-merges -- t/
    

git分支的新建与合并

  1. 查看分支

    git branch
    

    显示git 各个分支的版本

    [xxx@ops-monitor git]$ git branch -v
      dev    8b71aa6 24e24
    * master 8b71aa6 24e24
      test   6daa51f 12e1
    

    查看哪些分支合并进当前分支

    git branch --merged
    

    查看哪些分支未合并到当前分支

    git branch --no-merged
    
  2. 同步远程数据到本地

    git fetch origin
    
    git merge master
    
  3. 推送本地分支到远端(此方法会推送整个分支)

    git push (远程仓库名) (分支名):
    
  4. 新建一个分支,但是这个分支直接拉取远端某分支的数据

    git checkout -b [分支名] [远程名]/[分支名]
    
  5. 删除远端分支

    git push [远程名] :[分支名]
    

    远端

    git push origin --delete 分支名
    

    删除本地分支

    git branch -d 分支名
    
  6. 分支合并

    git merge --no-ff dev
    

    推荐分支

    推荐分枝策略

    衍合

    git checkout dev
    git rebase master
    git checkout master
    git merge dev
    
    图1

    图2

    图3

    图4

    多分支的衍合

    图1
    git rebase --onto master server client
    
    图2
    git checkout master
    git merge client
    
    图3
    git rebase master server
    
    图4
    git checkout master
    git merge server
    
    git branch -d client
    git branch -d server
    
    图5

    衍合的另一种解决

    图2

git 差分文件

  1. 查看未暂存的文件进行了哪些更新,比加参数直接git diff

    如果追踪了文件,可以用此命令差分(未追踪的文件,由于未追踪所以无法差分)

    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt
    [root@Jolay demo]# touch d.txt
    [root@Jolay demo]# echo hello > d.txt 
    [root@Jolay demo]# git diff
    [root@Jolay demo]# git add d.txt 
    [root@Jolay demo]# ls
    a.txt  b.txt  c.txt  d.txt
    [root@Jolay demo]# git diff
    [root@Jolay demo]# echo world > d.txt 
    [root@Jolay demo]# git diff
    diff --git a/d.txt b/d.txt
    index ce01362..cc628cc 100644
    --- a/d.txt
    +++ b/d.txt
    @@ -1 +1 @@
    -hello
    +world
    [root@Jolay demo]# 
    

    注意: 此条命令是比较工作目录中打给你钱文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容

  2. 已经暂存起来的文件,还没有提交的内容,可以用git diff --cached命令,或者是使用 git diff --staged

    [root@Jolay demo]# git show
    commit f82b272b2ce8b58a5278ab0997204e4f969617de
    Author: xxx 
    Date:   Wed Nov 9 01:08:44 2016 +0800
    
        end
    
    diff --git a/d.txt b/d.txt
    index ce01362..cc628cc 100644
    --- a/d.txt
    +++ b/d.txt
    @@ -1 +1 @@
    -hello
    +world
    [root@Jolay demo]# echo cao > d.txt 
    [root@Jolay demo]# git add .
    [root@Jolay demo]# echo ya > d.txt 
    [root@Jolay demo]# git diff
    diff --git a/d.txt b/d.txt
    index d30c5c8..865493f 100644
    --- a/d.txt
    +++ b/d.txt
    @@ -1 +1 @@
    -cao
    +ya
    [root@Jolay demo]# git diff --cached
    diff --git a/d.txt b/d.txt
    index cc628cc..d30c5c8 100644
    --- a/d.txt
    +++ b/d.txt
    @@ -1 +1 @@
    -world
    +cao
    [root@Jolay demo]#
    
  1. git 差分分支

    git diff master
    
  2. 如果感觉使用暂存区很繁琐,那么可以直接食用git commmit -a -m "" 参数,但是这样就无法使用暂存区的功能了,所以不推荐使用

    git commit -a -m " test -a var"
    
  3. git状态的保存

    git stash
    git stash pop
    git stash apply
    git stash -q
    

git忽略不需要提交的文件

  1. 忽略文件

    cat .gitignore

    *.[oa]
    *.a
    

    忽略所有.0和.a的文件

    我们再看一个 .gitignore 文件的例子:

    # Untracked files:
    # no .a files
    *.a
    .project
    .classpath
    *.iml
    
     # only ignore the TODO file in the current directory, not subdir. /TODO
    /TODO
    
    # ignore all files in the build/ directory
    build/
    target/
    .setttings/
    .idea/
    
     # ignore doc/notes.txt, but not doc/server/arch.txt
    doc/*.txt
    
    # ignore all .pdf files in the doc/ directory
    doc/**/*.pdf
    
    # Tracked files:
    # but do track lib.a, even though you're ignoring .a files above
    !lib.a
    !target/ROOT.war
    !/.gitignore
    

git撤消操作

  1. 修改最后一次提交

    有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend 选项重新提交:
    如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:

    $ git commit -m 'initial commit'
    $ git add forgotten_file
    $ git commit --amend
    

    上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。

  2. 对于已经暂存的文件可以使用撤销暂存的方式(注意是撤消暂存,而不是回滚文件)

    其实,git status 的命令输出已经告诉了我们该怎么做:就在 “Changes to be committed” 下面,括号中有提示,可以使用 git reset HEAD ... 的方式取消暂存。好吧,我们来试试取消暂存 benchmarks.rb 文件:

    $ git reset HEAD benchmarks.rb
    Unstaged changes after reset:
    M       benchmarks.rb
    $ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD ..." to unstage)
    
            modified:   README.txt
    
    Changes not staged for commit:
      (use "git add ..." to update what will be committed)
      (use "git checkout -- ..." to discard changes in working directory)
    
            modified:   benchmarks.rb
    
  3. 取消对文件的修改,git checkout

    git checkout -- benchmarks.rb
    

git远程仓库的使用

  1. 显示远端仓库(如果现实远端仓库的链接git remote -v

    git remote -v
    
  2. 要添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用,运行 git remote add [shortname] [url]

    $ git remote
    origin
    $ git remote add pb git://github.com/paulboone/ticgit.git
    $ git remote -v
    origin  git://github.com/schacon/ticgit.git
    pb  git://github.com/paulboone/ticgit.git
    
  3. 从远程仓库抓取数据

    git fetch [remote-name]
    

    例如:git fetch origin

    git pull
    

    推荐此种方法

  4. 推送数据到远程仓库

    git push [remote-name] [branch-name]
    
    git push origin master
    
  5. 查看远程仓库信息

    git remote show [remote-name] 
    
    git remote show origin
    

    它告诉我们,运行 git push 时缺省推送的分支是什么(译注:最后两行)。它还显示了有哪些远端分支还没有同步到本地(译注:第六行的 caching 分支),哪些已同步到本地的远端分支在远端服务器上已被删除(译注:Stale tracking branches 下面的两个分支),以及运行 git pull 时将自动合并哪些分支(译注:前四行中列出的 issues 和 master 分支)

  6. 远程仓库的删除和重命名

    重命名

    $ git remote rename pb paul
    $ git remote
    origin
    paul
    

    删除

    $ git remote rm paul
    $ git remote
    origin
    

git 打标签

  1. 列显已有的标签

    $ git tag
    v0.1
    v1.3
    

    显示的标签按字母顺序排列,所以标签的先后并不表示重要程度的轻重。

    我们可以用特定的搜索模式列出符合条件的标签。在 Git 自身项目仓库中,有着超过 240 个标签,如果你只对 1.4.2 系列的版本感兴趣,可以运行下面的命令:

    $ git tag -l 'v1.4.2.*'
    v1.4.2.1
    v1.4.2.2
    v1.4.2.3
    v1.4.2.4
    
  2. 含附注的标签

    Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。

    创建一个含附注类型的标签非常简单,用 -a (译注:取 annotated 的首字母)指定标签名字即可:

    $ git tag -a v1.4 -m 'my version 1.4'
    $ git tag
    v0.1
    v1.3
    v1.4
    

其中: -m 选项则指定了对应的标签说明,Git 会将此说明一同保存在标签对象中。如果没有给出该选项,Git 会启动文本编辑软件供你输入标签说明。

  1. 显示标签
    可以使用 git show 命令查看相应标签的版本信息,并连同显示打标签时的提交对象。

    $ git show v1.4
    
  2. 签署标签
    如果你有自己的私钥,还可以用 GPG 来签署标签,只需要把之前的 -a 改为 -s (译注: 取 signed 的首字母)即可:

    $ git tag -s v1.5 -m 'my signed 1.5 tag'
    
  3. 轻量级标签
    轻量级标签实际上就是一个保存着对应提交对象的校验和信息的文件。要创建这样的标签,一个 -a-s-m选项都不用,直接给出标签名字即可。

    $ git tag v1.4-lw
    $ git tag
    v0.1
    v1.3
    v1.4
    v1.4-lw
    v1.5
    
  4. 验证标签
    可以使用 git tag -v [tag-name] (译注:取 verify 的首字母)的方式验证已经签署的标签。此命令会调用 GPG 来验证签名,所以你需要有签署者的公钥,存放在 keyring 中,才能验证。

  5. 后期加注标签
    你甚至可以在后期对早先的某次提交加注标签。比如在下面展示的提交历史中:

    $ git log --pretty=oneline
    15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
    a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
    0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
    6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
    0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
    

    我们忘了在提交 “updated rakefile” 后为此项目打上版本号 v1.2,没关系,现在也能做。只要在打标签的时候跟上对应提交对象的校验和(或前几位字符)即可

    $ git tag -a v1.2 9fceb02
    

    可以看到我们已经补上了标签:

    $ git tag
    v0.1
    v1.2
    v1.3
    v1.4
    v1.4-lw
    v1.5
    
    $ git show v1.2
    tag v1.2
    Tagger: Scott Chacon 
    Date:   Mon Feb 9 15:32:16 2009 -0800
    
    version 1.2
    commit 9fceb02d0ae598e95dc970b74767f19372d61af8
    Author: Magnus Chacon 
    Date:   Sun Apr 27 20:43:35 2008 -0700
    
  6. 分享标签

    默认情况下,git push 并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname] 即可:

    $ git push origin v1.5
    Counting objects: 50, done.
    Compressing objects: 100% (38/38), done.
    Writing objects: 100% (44/44), 4.56 KiB, done.
    Total 44 (delta 18), reused 8 (delta 1)
    To [email protected]:schacon/simplegit.git
    * [new tag]         v1.5 -> v1.5
    

    如果要一次推送所有本地新增的标签上去,可以使用 --tags 选项:

    $ git push origin --tags
    Counting objects: 50, done.
    Compressing objects: 100% (38/38), done.
    Writing objects: 100% (44/44), 4.56 KiB, done.
    Total 44 (delta 18), reused 8 (delta 1)
    To [email protected]:schacon/simplegit.git
     * [new tag]         v0.1 -> v0.1
     * [new tag]         v1.2 -> v1.2
     * [new tag]         v1.4 -> v1.4
     * [new tag]         v1.4-lw -> v1.4-lw
     * [new tag]         v1.5 -> v1.5
    

    git push 完代码

    git push tag标签

    现在,其他人克隆共享仓库或拉取数据同步后,也会看到这些标签。

你可能感兴趣的:(Git学习笔记)