zoukankan      html  css  js  c++  java
  • Git笔记

    Git是什么?

    • 版本控制工具
    • 命令行程序

    Git能干什么?

    • 管理代码,控制版本
    • 同步文件

    本文不具体介绍怎么使用git,只做基本的概念解说,更多信息请参考git help

    Git是怎么工作的

    代码仓库(repository)

      进入软件源代码的根目录(项目文件夹),执行git init命令,会生成一个.git目录,.git目录里保存着git工作时所需的所有信息,它就是代码仓库。

    文件跟踪(track)

      通过git add <文件名>来跟踪某个文件。一个文件只有被git跟踪才会受到版本控制,可以通过git status命令来查看当前目录下的文件跟踪情况。

    git目录里的文件有这么几个状态

    • 未跟踪(untracked) 可以说是从没被git add过的文件
    • 未修改(unmodified) 指自从上次被提交后还没有过改动的文件
    • 已修改(modified) 指自从上次被提交后有过改动的文件
    • 已暂存(staged) 已修改状态的文件再次经过git add后会被暂存

    提交(commit)

      软件项目每完成一个阶段(添加了一个功能或者修复了一个bug等),都要提交一次,而且要有提交说明。每一次提交都会将相比上次提交有过改动的文件加入到repository里,可以通过git log命令来查看提交历史。

    分支(branch)

      git分支的出现是出于以下的需求:我的程序开发到一个稳定的阶段,我想添加一个新的功能,但是在开发的过程中可能会破坏程序原来的稳定性。怎样才能保证用户能正常使用程序原有的稳定的功能,又不耽误基于现有代码上的新功能的开发呢?如果没有git,我们会考虑将现有的代码拷贝一份保存起来,这样也不是很麻烦,可是我的代码每稳定一次就要完全保存一份,岂不是太麻烦了,而且有很多代码相比上次稳定的没有过改动。
      对于保存改动过的代码,我们自然想到了commit。我们可以把稳定的代码commit了,要用稳定版代码的时候再通过git reset系列命令reset回来。但是这样问题来了,我把开发版的代码reset到稳定版了,我再怎么回到开发版呢?
      于是乎,分支来了。我们可以在主分支上提交过稳定代码过后,通过git checkout -b dev命令新建并切换到dev分支,这样日后我们在dev分支里不管代码有过什么改动,都可以通过git checkout master命令切换到主分支,切换回来后代码会完好如初。用完master的代码,我们随时都可以再通过git checkout dev命令切换到dev分支,代码又变成了你正在开发的版本。等新功能开发完了,我们commit一下,再切换到master分支,用git merge dev命令将dev分支的代码合并过来,至此,我们的新功能才添加到主分支里。至于dev分支,如果不需要了,可以使用git branch -D dev命令删掉。

    远程分支(remote branch)

    删除远程仓库中的分支

    git push :dev ----- 删除远程仓库中的dev分支

    Git ignore

      在项目根目录下建立一个.gitignore文件,里面可以存放需要忽略的文件信息。文件名直接写,目录要在目录名后面加斜线/,可以使用通配符,不同的条目之前要单独成行。像下面这样的.gitignore文件:

    bin/
    test-*.c
    bugs.md
    

      git在跟踪文件会忽略bin目录,所有test-*.c形式的文件以及bugs.md文件,git status命令也不会提示这些文件未跟踪。

    Git深入

    Git内部对象

      Git将所有的跟踪信息都放在了.git目录里,我们的提交、分支等都是特定的对象,都被git以文件的形式保存在了.git目录里。.git目录像是我们在开发过程中的内存,里面的文件组织结构便是git的数据结构。一般不要直接修改.git目录里的文件,毕竟手动修改'内存'是很危险的,除非你对git内部的工作原理非常熟悉。

    • blob ----- 对应文件
    • tree ----- 对应目录
    • commit ----- 提交
      branch是在内部也是以commit的形式记录,或者说branch是特殊的commit。

    杂记

    不常用但很有用的命令

    没见过的命令要记得git help <>,或者度娘

    • git commit --amend 修定上次提交
    • git ls-tree 列出树对象
    • git clone --depth=1 <url> 只克隆最后一次提交
    • git rebase 删除以前没用的提交
    • git clone --recursive 递归克隆submodule

    Git reset 命令的三种方式

    1. git reset –mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息
    2. git reset –soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可
    3. git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容

    git revert

    Commit关系图

    图文来源于StackOverflow: http://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git

    G   H   I   J
     \ /     \ /
      D   E   F
       \  |  / \
        \ | /   |
         \|/    |
          B     C
           \   /
            \ /
             A
    A =      = A^0
    B = A^   = A^1     = A~1
    C = A^2  = A^2
    D = A^^  = A^1^1   = A~2
    E = B^2  = A^^2
    F = B^3  = A^^3
    G = A^^^ = A^1^1^1 = A~3
    H = D^2  = B^^2    = A^^^2  = A~2^2
    I = F^   = B^3^    = A^^3^
    J = F^2  = B^3^2   = A^^3^2
    

    最近的一次提交可以用HEAD表示,本例中A就是HEAD。G-D-B-A是主干(master)分支,C是A的次要祖先,B是A的直接祖先,当前分支的上级commit用,其它分支用^。多个、~1、1的效果是一样的,因为git在识别时会从左向右计算。

    参考资料

  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/luzhlon/p/7055393.html
Copyright © 2011-2022 走看看