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在识别时会从左向右计算。

    参考资料

  • 相关阅读:
    LeetCode 516. Longest Palindromic Subsequence
    LeetCode 432. All O`one Data Structure
    LeetCode 450. Delete Node in a BST
    LeetCode 460. LFU Cache
    LeetCode 341. Flatten Nested List Iterator
    LeetCode 381. Insert Delete GetRandom O(1)
    LeetCode 380. Insert Delete GetRandom O(1)
    LintCode Coins in a Line III
    LintCode Coins in a Line II
    LintCode Coins in a Line
  • 原文地址:https://www.cnblogs.com/luzhlon/p/7055393.html
Copyright © 2011-2022 走看看