Git學(xué)習(xí)筆記

git學(xué)習(xí)筆記

聲明

本文是本人學(xué)習(xí)Git過程中所做的筆記,以便日后查閱,文中多有錯(cuò)漏之處,不建議用作學(xué)習(xí)材料,文章內(nèi)容來自網(wǎng)絡(luò),如需學(xué)習(xí)請移步原文:

Git教程-廖雪峰的官網(wǎng)網(wǎng)站
Git遠(yuǎn)程操作講解-阮一峰的網(wǎng)絡(luò)日志

Git誕生

2002年BitMover授權(quán)Linux社區(qū)免費(fèi)使用BitKeeper版本控制系統(tǒng)
2005年有人試圖破解BitKeeper的協(xié)議導(dǎo)致BitMover要收回Linux社區(qū)的使用權(quán)限

Linus花費(fèi)兩周時(shí)間使用C語言寫了一個(gè)分布式版本控制系統(tǒng),即git

集中式&分布式

什么是集中式版本控制系統(tǒng)

  • 集中式版本控制系統(tǒng)的版本庫統(tǒng)一存放在中央服務(wù)器,每次編程時(shí)都要先從中央服務(wù)器取得最新版本,完成后再把自己的版本推送給服務(wù)器
  • 缺陷:需要聯(lián)網(wǎng)才能工作

分布式版本控制系統(tǒng)(distributed version control system)

  • 分布式版本控制系統(tǒng)沒有中央服務(wù)器,每臺(tái)電腦都是一個(gè)完整的版本庫,可以通過推送獲取最新版本

  • 優(yōu)點(diǎn):

    1. 沒有中央服務(wù)器,不需要聯(lián)網(wǎng)

    通常分布式版本控制系統(tǒng)中有一臺(tái)充當(dāng)服務(wù)器的電腦,方便交換大家的修改

    1. 安全性高:每個(gè)人的電腦都是版本庫
    2. Git的分支管理功能強(qiáng)大(branch)

安裝git

git命令可以查看系統(tǒng)有沒有安裝git

    $ git
    usage: git [--version] [--help] [-C <path>] [-c name=value]
       [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
       [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
       [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
       <command> [<args>]

Linux系統(tǒng)安裝

  • Linux 使用命令即可直接安裝
    sudo apt-get install git

Windows上安裝git

  • Windows上安裝git需要通過模擬Linux運(yùn)行環(huán)境來完成,這里直接使用msysgit下載地址

至此Git的安裝已經(jīng)完成,下面是Git的學(xué)習(xí)階段

Git學(xué)習(xí)-版本庫

  1. 什么是版本庫
    版本庫(Repository)又名倉庫,倉庫里的文件都可以由git管理起來,git會(huì)對每個(gè)文件的修改刪除進(jìn)行跟蹤,一遍將來的某個(gè)時(shí)刻可以還原

  2. 創(chuàng)建版本庫
    創(chuàng)建版本庫只需要?jiǎng)?chuàng)建一個(gè)文件夾然后通知Git講次文件夾作為倉庫管理

     $ mkdir gitlearn
     $ cd gitlearn
     $ pwd
     /c/Users/lc/learngit
     //創(chuàng)建git文件夾
     $ git init
     Initialized empty Git repository in C:/Users/lc/learngit/.git/
    
  3. 版本控制系統(tǒng)只能跟蹤文本的改動(dòng),不能跟蹤文本的內(nèi)容,Microsoft Word的格式是二進(jìn)制的,版本控制系統(tǒng)無法跟蹤改動(dòng)

Git學(xué)習(xí)-版本提交

  • 版本提交分為兩步
    1. git add <file>命令把文件添加到暫存區(qū)
    2. git commit命令告知Git,將文件提交到倉庫
      $ git commit -m "wrote a readme file"
      //-m 命令是對本次提交的說明,輸入本次提交的內(nèi)容

Git學(xué)習(xí)-時(shí)空穿梭

git status命令可以查看是否有文件被修改過

git status 主要用于查看倉庫當(dāng)前狀態(tài),比如哪些文件被修改,是否準(zhǔn)備提交

git diff可以查看修改的內(nèi)容

只限于文件被添加到暫存區(qū)之前,一旦執(zhí)行了git add命令,git diff就不能查看更改了

          git diff 常用的命令
          HEAD commit版本
          Index staged版本
          git diff//比較工作目錄和暫存區(qū)快照之間的差異
                 //即修改單還沒有暫存的內(nèi)容
          git diff --cached
          git diff --staged
          //未發(fā)現(xiàn)區(qū)別

          git diff HEAD
          //顯示工作版本(work tree)和HEAD之間的查表

          git diff topic master
          git diff topic..master
          //顯示兩個(gè)分支最新提交的區(qū)別
          git diff HEAD^ HEAD
          //顯示上次提交commit和上上次提交之間的差別

git add的各種區(qū)別

      git add -A   // 添加所有改動(dòng)
      git add *     // 添加新建文件和修改,但是不包括刪除
      git add .    // 添加新建文件和修改,但是不包括刪除
      git add -u   // 添加修改和刪除,但是不包括新建文件

在commit前撤銷add:

    git reset <file> // 撤銷提交單獨(dú)文件
    git reset        // unstage all due changes

add/commit前撤銷對文件的修改:

    git checkout -- README.md  // 注意, add添加后(同commit提交后)就無法通過這種方式撤銷修改

Git學(xué)習(xí)-版本回退

查看歷史記錄:

    $ git log
    //長串的編碼是commit id(版本號)
    commit 75d2bf408c157c0b5c9255f81a6dd7116670f1cb
    Author: Shenglong <liushenglong@wemarklinks.com>
    Date:   Tue Jun 27 11:45:28 2017 +0800

        2.0 version

    commit 2b9e2e1c667378bf00662c173d70581724d53bd0
    Author: Shenglong <liushenglong@wemarklinks.com>
    Date:   Tue Jun 27 11:13:53 2017 +0800

        find some Syntax Error

    commit b193cdc3b9951c23279d45e04aed326ec3a866c5
    Author: Shenglong <liushenglong@wemarklinks.com>
    Date:   Tue Jun 27 09:52:12 2017 +0800

        test git

Git中 HEAD表示當(dāng)前版本,HEAD表示上一個(gè)版本,HEAD^ 表示上上個(gè)版本
HEAD~100表示向上100個(gè)版本

版本回退git reset

    $ git reset --hard HEAD^
    HEAD is now at 2b9e2e1 find some Syntax Error
    //已經(jīng)回退到上一個(gè)版本

再來查看版本庫的狀態(tài)

    $ git log
    commit 2b9e2e1c667378bf00662c173d70581724d53bd0
    Author: Shenglong <liushenglong@wemarklinks.com>
    Date:   Tue Jun 27 11:13:53 2017 +0800

        find some Syntax Error

    commit b193cdc3b9951c23279d45e04aed326ec3a866c5
    Author: Shenglong <liushenglong@wemarklinks.com>
    Date:   Tue Jun 27 09:52:12 2017 +0800

        test git

回退了一個(gè)版本,可以通過之前的版本id恢復(fù)版本或者繼續(xù)回退

    $ git reset --hard 75d2bf408c

查看readme.txt內(nèi)容

    $ cat readme.txt
    git is a distributed version control System
    i'm alittle confuse about how this worked
    git is free software

版本回退的原理:Git內(nèi)部有一個(gè)指向當(dāng)前版本的HEAD指針,回退版本的時(shí)候git僅僅是把指針前移了一位

后悔藥:git reflog,回退一個(gè)版本之后如果想退回原來的版本必須使用之前版本的commit id,然后使用git reset --hard commit id即可返回最新提交的版本

Git學(xué)習(xí)-工作區(qū)與暫存區(qū)

工作區(qū)(Working Directory)工作目錄
版本庫(Repository)工作區(qū)有一個(gè)隱藏目錄,版本庫中包含stage(暫存區(qū)也可以稱為Index),以及Git創(chuàng)建的第一個(gè)分支master,以及指向master的一個(gè)指針HEAD

0.jpg

Git學(xué)習(xí)-管理修改

git commit的作用是將暫存區(qū)中的修改應(yīng)用到版本庫中,未提交到暫存區(qū)的修改不會(huì)保存

git diff HEAD --readme.txt可以查看工作區(qū)里和版本庫里最新版本的區(qū)別

Git學(xué)習(xí)-撤銷修改

在修改未被提交到工作區(qū)之前可以使用git checkout -- <file>命令丟棄工作區(qū)的修改

exam:

    $ cat readme.txt
    git is a distributed version control System
    i'm alittle confuse about how this worked
    git is free software
    git is full of fun!
    wrong message(i don't wanna this to be commit)
    //我在這里犯了個(gè)錯(cuò)誤,但是修改還沒有被提交到暫存區(qū)
    //于是..
    $ git checkout -- readme.txt
    //這里看起來什么都沒有發(fā)生
    $ cat readme.txt
    git is a distributed version control System
    i'm alittle confuse about how this worked
    git is free software
    git is full of fun!
    //但是我錯(cuò)誤的修改已經(jīng)被丟棄了

如果修改被提交到暫存區(qū),可以使用git reset丟棄暫存區(qū)的記錄回到上一步,然后丟棄工作區(qū)的記錄即可

Git學(xué)習(xí)-刪除文件

如果不小心刪除了工作區(qū)的文件,git status查看時(shí)git 會(huì)告訴你哪些文件被刪除了

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

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

此時(shí)有兩個(gè)選擇:

  1. 從版本庫中刪除改文件

     $ git rm test.txt
     rm test.txt
     $ git commit
     $ git commit
     [master 502080a] test.txt has been removed
     1 file changed, 1 deletion(-)
     delete mode 100644 test.txt
     //此時(shí)版本庫和文件系統(tǒng)中都沒有test.txt了
    
  2. git checkout -- <file>如果誤刪了文件可以使用這個(gè)命令,用版本庫中的版本替換工作區(qū)中的版本

> `git checkout`命令本質(zhì)是從版本去檢出版本替換掉工作區(qū)的版本,雖然可以將文件恢復(fù)到最新版本,但是會(huì)丟失最近修改的內(nèi)容

遠(yuǎn)程倉庫

準(zhǔn)備工作

  1. 創(chuàng)建SSH Key

     $ ssh-keygen -t rsa -C "email@url.com"
     Your identification has been saved in /c/Users/lc/.ssh/id_rsa.
     Your public key has been saved in /c/Users/lc/.ssh/id_rsa.pub.
     The key fingerprint is:
     SHA256:R0Qr3PkLDR7RD4Xrn1pUWrzo+TpA+tusnr0eMYT3qB4 liushenglong@wemarklinks.com
     The key's randomart image is:
     +---[RSA 2048]----+
     |         .+. o.  |
     |       . o +=  . |
     |        o B. *  +|
     |         + *+ =+.|
     |        S *.o=oo |
     |         o o+o+  |
     |          .Eo=.. |
     |          ..*o=  |
     |          .*=O+. |
     +----[SHA256]-----+
    
  2. 登錄GitHub(Gitlab),進(jìn)入Account setting,"SSH Key"頁面,在Add SSH Key中填入id_rsa.pub中的內(nèi)容

添加遠(yuǎn)程庫

  1. 在git上創(chuàng)建庫 new Repository

  2. 在本地添加遠(yuǎn)程庫

     $ git remote add origin https://GitHub.com/Sakura3754/learngit.git
     //把本地庫推送到遠(yuǎn)程庫上
     $ git push -u origin master
     //第一次向遠(yuǎn)程庫推送時(shí)使用了-u參數(shù).Git不但把本地的master分支推送到遠(yuǎn)程新的master分支,還會(huì)把本地的master分支和遠(yuǎn)程的master分支關(guān)聯(lián)起來
    
0.png

提交完成

  1. 從現(xiàn)在起,只要本地做了提交就可以通過git push origin master提交到遠(yuǎn)程庫

從遠(yuǎn)程庫克隆

git clone git@github.com:Sakura3754/gitskills.git

分支管理

分支就是科幻電影里面的平行宇宙,當(dāng)你正在電腦前努力學(xué)習(xí)Git的時(shí)候,另一個(gè)你正在另一個(gè)平行宇宙里努力學(xué)習(xí)SVN。

創(chuàng)建與合并分支

每次提交,git將操作記錄串成一條時(shí)間線,這條時(shí)間線是一個(gè)分支,在git里這個(gè)分支叫主分支,即master分支.嚴(yán)格來說HEAD不是指向commit,而是指向master,master才是指向commit的

1.png

當(dāng)我們創(chuàng)建分支,例如dev時(shí),Git新建一個(gè)指針叫dev,指向master相同的提交,再把HEAD指向dev就表示當(dāng)前分支在dev上

2.png

從現(xiàn)在開始,對工作區(qū)的修改和提交就是針對dev分支了,比如新提交一次后,dev指針往前移動(dòng)一步,master指針不變

4.png

合并分支:將master指向dev當(dāng)前的提交就完成了分支的合并

3.png

刪除分支就是把指針刪除掉

實(shí)戰(zhàn):

  1. 創(chuàng)建分支

    $ git checkout -b dev//-b 表示創(chuàng)建并切換
    Switched to a new branch 'dev'
    //上面的命令等價(jià)于
    git branch dev//創(chuàng)建分支
    git checkout dev//切換分支

  2. git branch查看當(dāng)前分支

- 創(chuàng)建分支`git branch dev`
- 切換分支`git checkout dev`
- 創(chuàng)建并切換分支`git checkout -b dev`
- 查看當(dāng)前分支`git branch`
- 合并分支到當(dāng)前分支`git merge dev`
- 刪除分支`git branch -d dev`
- 合并沖突時(shí)必須手動(dòng)解決之后再提交

分支管理

  1. 如果使用Fast forword 模式合并分支,刪除分支后會(huì)丟掉分支信息,可以使用--no-ff參數(shù)禁用fast forword模式
> 使用no-ff模式提交時(shí),由于master不能直接將指針指向dev分支的最新提交,所以master分支只能獨(dú)立進(jìn)行一次提交操作,因此有內(nèi)容一樣,但是commit id不同的問題
  1. 分支管理原則:
* `master`分支應(yīng)該是非常穩(wěn)定的,僅用來發(fā)布新版本,不能在上面干活
* 所有的操作都在`dev`分支上進(jìn)行
* 團(tuán)隊(duì)成員都在dev上干活,每個(gè)人有自己的分支,時(shí)不時(shí)往`dev`上合并就可以了

BUG分支

  • 用臨時(shí)分支來修復(fù)bug時(shí),可以將當(dāng)前分支未提交的內(nèi)容儲(chǔ)存到stash中,等bug修復(fù)完成后繼續(xù)操作
    • git stash保存當(dāng)前工作進(jìn)度
    • git stash list讀取保存的進(jìn)度列表
    • git stash apply將保存的進(jìn)度恢復(fù)到工作區(qū)但是保留stash中的存檔
    • git stash drop刪除保存的stash
    • git stash pop取出存檔,同時(shí)刪除stash
    • git apply stash@{0}恢復(fù)指定的stash

Feature分支

  • 在添加一個(gè)新功能之前,為了防止實(shí)驗(yàn)代碼影響主分支內(nèi)容可以創(chuàng)建一個(gè)feature分支,在上面開發(fā)完成后合并
  • 丟棄一個(gè)沒有被合并過的分支可以通過git branch -D強(qiáng)行刪除

多人協(xié)作

  • 查看遠(yuǎn)程庫的信息

    • git remote
    • git remote -v查看更加詳細(xì)的信息
  • 分支推送

    • git push origin dev
    • master分支時(shí)主分支,因此要隨時(shí)與遠(yuǎn)程庫同步
    • dev 時(shí)開發(fā)分支,所有成員在上面工作,所以也需要同步
    • bug分支無需推送
    • feature 是否推送取決于是否有多人協(xié)同開發(fā)
  • 抓取分支

    • 從遠(yuǎn)程庫克隆時(shí),只能看到遠(yuǎn)程庫的master分支,如果要在dev分支上開發(fā),就必須創(chuàng)建遠(yuǎn)程的dev分支到本地

        $ git checkout -b dev origin/dev
        $ git pull <remote> <branch>
      
    • dev上修改并時(shí)不時(shí)推送到遠(yuǎn)程

        $ git push origin dev
      
    • 如果碰巧別人也push了對同樣文件的修改,則會(huì)發(fā)生沖突導(dǎo)致提交失敗,這是可以用git pull

        //如果提示no tracking information,說明本地分支尚未與遠(yuǎn)程分支建立連接
        //指定本地dev分支與遠(yuǎn)程origin分支的鏈接
        $ git branch --set-upstream dev origin/dev
        $ git pull
        //手動(dòng)解決沖突之后commit,push
        $ git commit
        $ git push origin dev
      

標(biāo)簽管理

創(chuàng)建標(biāo)簽

  • 創(chuàng)建一個(gè)標(biāo)簽,總共分三步

    1. 切換到需要打標(biāo)簽的分支git checkout <name>
    2. 打標(biāo)簽 git tag <tagname>
    3. 查看標(biāo)簽git tag

    git show <tagname>查看標(biāo)簽信息

  • 給一個(gè)只有id 的commit打標(biāo)簽

    1. git log --pretty=oneline --abbrev-commit找到歷史提交的commit id
    2. 打標(biāo)簽git tag <tagname> <commitid>
  • git tag -a <tagname> -m <message> <commitid>創(chuàng)建帶有說明的標(biāo)簽,-a指定標(biāo)簽名,-m添加說明文字

  • -s命令可以用PGP簽名標(biāo)簽

操作標(biāo)簽

  • 刪除標(biāo)簽git tag -d <tagname>
  • 推送標(biāo)簽到遠(yuǎn)程git push origin <tagname>
  • 一次推送全部標(biāo)簽git push origin --tags
  • 刪除遠(yuǎn)程標(biāo)簽
    • 先刪除本地標(biāo)簽git tag -d <tagname>
    • 然后從遠(yuǎn)程刪除

自定義Git

忽略指定文件

  • .gitignore文件中配置需要忽略的文件名,可以使用正則
  • .gitignore文件提交到版本庫
  • 檢驗(yàn).gitignore是否生效的標(biāo)準(zhǔn)是git status命令提示working directory clean

配置別名

  • 使用git config --global alias.<alias> <order>為命令指定別名

  • 花哨的小技巧

        //修改git log的字體樣式
        git config --global alias.log "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
    

補(bǔ)充

Git clone

  • 用法

      git clone (-o 主機(jī)名) <url> <localdir>
    
  • git clone 支持多種協(xié)議

      $ git clone http[s]://example.com/path/to/repo.git/
      $ git clone ssh://example.com/path/to/repo.git/
      $ git clone git://example.com/path/to/repo.git/
      $ git clone /opt/git/project.git
      $ git clone file:///opt/git/project.git
      $ git clone ftp[s]://example.com/path/to/repo.git/
      $ git clone rsync://example.com/path/to/repo.git/
    

remote補(bǔ)充

    $ git remote show <主機(jī)名>
    //查看主機(jī)信息
    $ git remote add <主機(jī)名> <網(wǎng)址>
    //添加主機(jī)
    $ git remote rm <主機(jī)名>
    //刪除主機(jī)
    $ git remote rename <原主機(jī)名> <新主機(jī)名>
    //遠(yuǎn)程主機(jī)改名

git fetch

  • git fetch 通常用于將遠(yuǎn)程主機(jī)的更新(commit)取回本地

     $ git fetch <遠(yuǎn)程主機(jī)名>
     //將遠(yuǎn)程主機(jī)上所有分支取回本地
     $ git fetch <遠(yuǎn)程主機(jī)名> <分支名>
     //將指定分支取回本地
    
  • git fetch取回的更新要用"遠(yuǎn)程主機(jī)名/分支名"的形式讀取

  • git branch -r查看遠(yuǎn)程分支

  • git branch -a查看所有分支

  • 取回遠(yuǎn)程分支后

      //可以在遠(yuǎn)程分支的基礎(chǔ)上創(chuàng)建一個(gè)新的分支
      $ git checkout -b newbranch
      //也可以在本地分支上合并遠(yuǎn)程分支
      $ git merge origin/master
      $ git rebase origin/master
    
  • git pull/push

      $ git pull <遠(yuǎn)程主機(jī)名> <遠(yuǎn)程分支>:<本地分支>
      $ git pull <遠(yuǎn)程主機(jī)名> <本地分支>:<遠(yuǎn)程分支>
      //手動(dòng)建立本地分支與遠(yuǎn)程分支的追蹤關(guān)系
      $ git branch --set-upstream <本地分支> <遠(yuǎn)程主機(jī)/遠(yuǎn)程分支>
    
  • git push的特殊用法

      //省略遠(yuǎn)程分支,默認(rèn)推送到與之有"追蹤關(guān)系"的遠(yuǎn)程分支
      $ git push origin master
      //向遠(yuǎn)程推送空分支相當(dāng)于刪除origin主機(jī)上的對應(yīng)分支
      $ git push origin :master
      #等同于
      $ git push origin --delete master
      # 如果當(dāng)前分支與多個(gè)遠(yuǎn)程主機(jī)關(guān)聯(lián)可以使用`-u`指定默認(rèn)遠(yuǎn)程分支
      $ git push -u origin master
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容