3. Git 基本操作

了解 Linux 常見命令

在使用 git 前,建議事先熟悉一些常見的 bash 命令

進(jìn)入xxx目錄
$ cd xxx

移動(dòng)
$ mv [old-name] [new-name]

刪除單個(gè)文件
$ rm test.txt刪除當(dāng)前目錄下的一個(gè)文件

當(dāng)前目錄下建立文件夾
$ mkdir [folder-name]

顯示當(dāng)前目錄
$ pwd

查看該目錄下的文件和文件夾
$ ls -al

查看該目錄下的文件和文件夾包含隱藏目錄
$ ls -ah

配置 config

可以通過git config rexx.aa.bb cc, git config aa.bb.cc 'dd' 進(jìn)行設(shè)置。
每一條命令都在.git/config文件中添加一行。如果該遠(yuǎn)程部分不存在,那么你發(fā)出的第一條命令將在該文件中為它創(chuàng)建。

[rexx "aa"]
    bb = cc
[aa "bb"]
    cc = dd
  • git config -l, --list 列舉完整配置文件內(nèi)容
  • git config --list --local 列舉出 local 所有配置
  • git config --list --global 列舉出 global 所有配置
  • git config --list --system 列舉出 system 所有配置

查看配置 config 文件

配置Git的時(shí)候,加上 --global 是針對(duì)當(dāng)前用戶起作用的,如果不加,那只針對(duì)當(dāng)前的倉庫起作用。每個(gè)倉庫的 Git 配置文件都放在.git/config 文件中。因?yàn)榕渲梦募皇呛?jiǎn)單的文本文件,所以可以通過 cat 命令來查看其內(nèi)容, 也可以通過你最喜歡的文本編輯器來編輯它。

$ cat .git/config 

別名就在[alias]后面,要?jiǎng)h除別名,直接把對(duì)應(yīng)的行刪掉即可。

而當(dāng)前用戶的 Git 配置文件放在用戶主目錄下的一個(gè)隱藏文件.gitconfig中:

$ cat .gitconfig
[alias]
    co = checkout
    ci = commit
    br = branch
    st = status
[user]
    name = Your Name
    email = your@email.com

初始化 init

git init 在當(dāng)前目錄初始化倉庫
git init [path] 初始化倉庫
git init [path] --bare 初始化一個(gè)裸倉庫

Git不關(guān)心你是從一個(gè)完全空白的目錄還是由一個(gè)裝滿文件的目錄開始的。在這兩種情況下,將目錄轉(zhuǎn)換到Git版本庫的過程是一樣的。

細(xì)心的讀者可以發(fā)現(xiàn)在 init 之后,目錄下多了一個(gè).git 的目錄,這個(gè)目錄是 Git 來跟蹤管理版本庫的,沒事千萬不要手動(dòng)修改這個(gè)目錄里面的文件,不然改亂了,就把 Git 倉庫給破壞了。

PS:如果你沒有看到 .git 目錄,那是因?yàn)檫@個(gè)目錄默認(rèn)是隱藏的

一個(gè)Git版本庫要么是一個(gè)裸(bare)版本庫,要么是一個(gè)開發(fā)(非裸)
(development, nonbare)版本庫。開發(fā)版本庫用于常規(guī)的日常開發(fā)。它保持當(dāng)前分支的概念,并在工作目錄中提供檢出當(dāng)前分支的副本。相反,一個(gè)裸版本庫沒有工作目錄,并且不應(yīng)該用于正常開發(fā)。裸版本庫也沒有檢出分支的概念。裸版本庫可以簡(jiǎn)單地看做git目錄的內(nèi)容。換句話說,不應(yīng)該在裸版本庫中進(jìn)行提交操作。

按照慣例,裸版本庫名有個(gè).git 后綴。這不是必需的,但認(rèn)為這是最佳實(shí)踐。

查看工作區(qū)狀態(tài) status

git status

-s, --short
Give the output in the short-format.

git status 命令目前是否有暫存的變更需要提交,工作目錄是否是干凈(clean)的等信息。 經(jīng)常檢查當(dāng)前狀態(tài)是個(gè)好習(xí)慣

工作目錄干凈意味著工作目錄里不包含任何與版本庫中不同的未知或者更改過的文件。

查看幫助 help

$ git help <command> / $ git <command> --help 獲取幫助

-w, --web
以網(wǎng)頁(HTML)格式顯示命令的手冊(cè)頁

文件至?xí)捍鎱^(qū) add

這是個(gè)多功能命令,根據(jù)目標(biāo)文件的狀態(tài)不同,此命令的效果也不同:可以用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區(qū),還能用于合并時(shí)把有沖突的文件標(biāo)記為已解決狀態(tài)等
git add [filename1] [filename2] ...//可以一次提交很多文件
例如
$ git add src/com/abc/MainActivity.java add單個(gè)文件
$ git add src/ add單個(gè)文件夾
$ git add .添加對(duì)應(yīng)目錄下所有文件和文件夾

git add -A 提交所有變化
git add . 提交新文件(new)和被修改(modified)文件,不包括被刪除(deleted)文件
git add -u 提交被修改(modified)和被刪除(deleted)文件,不包括新文件(new)

例如本次刪除了一個(gè)已被 git 管理的文件 rm 1.txt
則可以通過 git add -u 將此次變更提交至?xí)捍鎱^(qū)。也可以鍵入 git rm 1.txt 或者 git add 1.txt 達(dá)到同樣的目的。

git-diff - Show changes between commits

$ git diff git diff會(huì)顯示工作目錄和索引之間的差異。
$ git diff commit 會(huì)顯示工作目錄和給定提交間的差異。常見的一種用法是用HEAD或者一個(gè)特定的分支名作為commit
$ git diff --cached commit (或 --staged Git 1.6.1 及更高版本上允許使用,效果相同), 顯示索引中的變更中和給定提交中的變更之間的差異。如果省略 commit這一項(xiàng),則默認(rèn)為HEAD,使用HEAD,該命令會(huì)顯示下次提交會(huì)如何修改當(dāng)前分支。

注:如果拼接上 -- [filename] 表示比較特定文件的差異。

可以用 git diff 的這兩種形式引導(dǎo)你完成暫存變更的過程。最初, git diff顯示所有修改的大集合, --cached則是空的。而當(dāng)暫存時(shí),前者的集合會(huì)收縮,后者會(huì)增大。如果所有修改都暫存了并準(zhǔn)備提交,--cached將是滿的,而git diff則什么都不顯示。

$ git diff [<commit-id1>] [<commit-id2>] 比較兩個(gè)commit-id之間的差異
$ git diff [<commit-id1>] [<commit-id2>] -- abc.txt edf.md 比較兩個(gè)commit-id之間指定文件的差異

舉例:為了查看兩個(gè)版本之間的差異,使用兩個(gè)提交的全I(xiàn)D名并且運(yùn)行 git diff

 $ git diff 9da581d910c9c4ac93557ca4859e767f5caf5169 \
 ec232cddfb94e9dfd5b5855af8ded7f5eb5c9ed6

刪除 rm

git rm 命令自然是與 git add 相反的命令。它會(huì)在版本庫和工作目錄中同時(shí)刪除文件。

注意:git rm 也是一條對(duì)索引進(jìn)行操作的命令,所以它對(duì)沒有添加到版本庫或索引中的文件是不起作用的; Git必須先認(rèn)識(shí)到文件才行。

$ git rm 從暫存區(qū)和工作區(qū)刪除, 直接做了本地 rm 和 add/rm 到暫存區(qū)的操作.
$ git rm --cached readme.txt 僅從暫存區(qū)刪除,和add 命令相對(duì).
但仍希望保留在當(dāng)前工作目錄中。換句話說,僅是從跟蹤清單中刪除。比如一些大型日志文件或者一堆 .a 編譯文件,不小心納入倉庫后,要移除跟蹤但不刪除文件,以便稍后在 .gitignore文件中補(bǔ)上.
$ git rm $(git ls-files --deleted): 刪除所有被跟蹤, 但是在工作區(qū)總被刪除的文件

移動(dòng) | 重命名 mv

$ git mv [oldFile] [newFile]
其實(shí),運(yùn)行 git mv 就相當(dāng)于運(yùn)行了下面三條命令:

mv README.txt README
git rm README.txt
git add README

Git 在對(duì)文件的移動(dòng)操作上與其他同類系統(tǒng)不同,它利用一個(gè)基于兩個(gè)文件版本內(nèi)容相似度的機(jī)制。

Git 的強(qiáng)大功能是即使經(jīng)歷過重命名,也仍然能保留對(duì)文件歷史記錄的追蹤。
在使用 git --follow log 選項(xiàng)會(huì)讓 Git 在日志中回溯并找到內(nèi)容相關(guān)聯(lián)的整個(gè)歷史記錄。

示例

 $ git Log --follow README

還原工作區(qū)文件 | 切換分支 checkout

$ git checkout -- <file>...(to discard changes in working directory)

將文件內(nèi)容從暫存區(qū)復(fù)制到工作目錄

舉例git checkout -- readme.txt意思就是,把readme.txt文件在工作區(qū)的修改全部撤銷,
這里有兩種情況:
一種是 readme.txt 自修改后還沒有被放到暫存區(qū),現(xiàn)在,撤銷修改就回到和版本庫一模一樣的狀態(tài);
一種是 readme.txt 已經(jīng)添加到暫存區(qū)后,又作了修改,現(xiàn)在,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)。

舉例
git checkout -- README.MD
git checkout -- .
git checkout HEAD -- .

在Git中,HEAD 始終指向當(dāng)前分支的最近提交。當(dāng)切換分支時(shí), HEAD 會(huì)更新為指向新分支的最近提交。

在同一代提交中,插入符號(hào)^是用來選擇不同的父提交的。給定一個(gè)提交C, C^1是其第一個(gè)父提交, C^2是其第二個(gè)父提交, C^3是其第三個(gè)父提交.

波浪線~用于返回父提交之前并選擇上一代提交。同樣,給定一個(gè)提交C, C~1是其第一個(gè)父提交, C-2是其第一個(gè)祖父提交, C-3是第一個(gè)曾祖父提交。當(dāng)在同一代中存在多個(gè)父提交時(shí),緊跟其后的是第一個(gè)父提交的第一個(gè)父提交。你可能會(huì)注意到,C^1和C~1都指的是C的第一個(gè)父提交,兩個(gè)名字都是對(duì)的, 如圖所示。

總之,就是讓這個(gè)文件回到最近一次 git commit 或 git add 時(shí)的狀態(tài)
這條命令有些危險(xiǎn),所有對(duì)文件的修改都沒有了,因?yàn)槲覀儎倓偘阎鞍姹镜奈募?fù)制過來重寫了此文件。所以在用這條命令前,請(qǐng)務(wù)必確定真的不再需要保留剛才的修改。

針對(duì)分支
$ git checkout - 切換到上一個(gè)分支
$ git checkout [commit id] 表示當(dāng)前 HEAD 指針指向某一個(gè)commit id, commid可以是分支名稱,表示切換到該分支.

我們發(fā)現(xiàn)在使用 checkout 操作工作區(qū)的文件時(shí),通過“裸雙破折號(hào)”的約定來分離一系列參數(shù)。因此建議操作文件的時(shí)候建議顯式加上 -- 。

# Checkout the tag named "main.c"
$ git checkout main.d

# Checkout the file named "main.c" 
$ git checkout -- main.c

提交在暫存區(qū)的修改 commit

$ git commit -m 'initial project version'
注意: Git 只不過暫存了你運(yùn)行 git add 命令時(shí)的版本, 而非當(dāng)前工作目錄中的版本。
每次修改,如果不add到暫存區(qū),那就不會(huì)加入到commit中

跳過使用暫存區(qū)域
$ git commit -a/--all -m 'added new benchmarks'
跳過使用暫存區(qū)域的方式,只要在提交的時(shí)候,給git commit 加上 -a 選項(xiàng),Git 就會(huì)自動(dòng)把所有已經(jīng)跟蹤過的文件暫存起來一并提交,從而跳過 git add 步驟, 如果有未跟蹤的文件還是需要先進(jìn)行 add。

對(duì)于普通的git commit命令, git commit--amend 會(huì)彈出編輯器會(huì)話,可以在里面修改提交消息。
git commit --amend

也可以直接修改最后一次提交的注釋
$ git commit --amend -m "someMessage"

git commit --amend 事實(shí)上可以作為新提交的一部分添加或刪除文件。要做到這一點(diǎn),先改正工作目錄中的文件。更正錄入錯(cuò)誤然后根據(jù)需要添加或刪除文件。跟任何提交一樣,使用命令更新索引,如git add或git rm。然后發(fā)出git commit --amend命令。

--amend 這條命令還可以編輯提交的元信息。例如,通過指定--author可以改變提交的作
者。git commit -amend--author "Bob Miller <kbobgexample.com"

查看提交歷史 log

git log

# 等價(jià)于
git log HEAD

-num 參數(shù)表示我們只想看到num行記錄.
-p 按補(bǔ)丁格式顯示每個(gè)更新之間的差異。
--stat 顯示每次更新的文件修改統(tǒng)計(jì)信息, 包含增改行數(shù)統(tǒng)計(jì)
--shortstat 只顯示 --stat 中最后的行數(shù)修改添加移除統(tǒng)計(jì)。
--name-only 僅在提交信息后顯示已修改的文件清單。
--name-status 顯示新增、修改、刪除的文件清單。
--abbrev-commit 僅顯示 SHA-1 的前幾個(gè)字符,而非所有的 40 個(gè)字符。
--relative-date 使用較短的相對(duì)時(shí)間顯示(比如,“2 weeks ago”)。
--graph 顯示 ASCII 圖形表示的分支合并歷史。
--pretty 使用其他格式顯示歷史提交信息。可用的選項(xiàng)包括 oneline,short,full,fuller 和 format(后跟指定格式)。

--oneline 一行顯示
--author 【貢獻(xiàn)者名字】
--log --graph 圖示法顯示提交歷史
--reverse 提交版本默認(rèn)是按照時(shí)間倒序排序,如果需要正序可以加上該參數(shù)

查看命令歷史 git reflog

git reflog
查看命令歷史

重置 HEAD 指針到特殊狀態(tài)| reset 命令

暫存區(qū)可以類比為加入購(gòu)物車.

取消已經(jīng)暫存的文件, 與 add 相對(duì)
$ git reset 所有當(dāng)前暫存區(qū)的內(nèi)容, 和 HEAD保持一致
$ git reset HEAD 同上
$ git reset HEAD <file>... 同上, 取消暫存區(qū)部分文件
$ git reset HEAD -- <file>... 同上

  • 將當(dāng)前分支回退到某個(gè)歷史版本
git reset commit-id

$ git reset --mixed commit_id 【默認(rèn)】它將重置HEAD到另外一個(gè)commit,并且重置 index 以便和 HEAD 相匹配,但是也到此為止。working copy不會(huì)被更改。
$ git reset --soft commit_id
$ git reset --hard commit_id

--soft會(huì)將 HEAD 引用指向給定提交。索引和工作目錄的內(nèi)容保持不變。這個(gè)版本的命令有“最小”影響, 只改變一個(gè)符號(hào)引用的狀態(tài)使其指向一個(gè)新提交。

--mixed 會(huì)將HEAD指向給定提交。索引內(nèi)容也跟著改變以符合給定提交的樹結(jié)構(gòu),但是工作目錄中的內(nèi)容保持不變。這個(gè)版本的命令將索引變成你剛剛暫存該提交全部變化時(shí)的狀態(tài),它會(huì)顯示工作目錄中還有什么修改。
注意, --mixed是git reset的默認(rèn)模式。

--hard 這條命令將HEAD引用指向給定提交。索引的內(nèi)容也跟著改變以符合給定提交的樹結(jié)構(gòu)。此外,工作目錄的內(nèi)容也隨之改變以反映給定提交表示的樹的狀態(tài)。
當(dāng)改變工作目錄的時(shí)候,整個(gè)目錄結(jié)構(gòu)都改成給定提交對(duì)應(yīng)的樣子。做的修改都將丟失,新文件將被刪除。在給定提交中但不在工作目錄中的文件將恢復(fù)回來。

例如:
例如回退到上個(gè)版本git reset --hard HEAD^

reset 和 checkout 的差異

推薦一個(gè)學(xué)習(xí) git 的網(wǎng)站

https://learngitbranching.js.org/

重置關(guān)卡 reset

查看答案 show solution

參考

Git版本控制管理(第2版)-異步社區(qū)
https://www.epubit.com/bookDetails?id=N8405

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,610評(píng)論 1 26
  • Git常用語法 [TOC] Git簡(jiǎn)介 描述 ? Git(讀音為/g?t/。)是一個(gè)開源的分布式版本控制系統(tǒng),...
    君惜丶閱讀 3,584評(píng)論 0 13
  • 1.git的安裝 1.1 在Windows上安裝Git msysgit是Windows版的Git,從https:/...
    落魂灬閱讀 12,713評(píng)論 4 54
  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,721評(píng)論 9 163
  • 記得早先少年時(shí) 大家誠(chéng)誠(chéng)懇懇 說一句是一句 清早上火車站 長(zhǎng)街黑暗無行人 賣豆?jié){的小店冒著熱氣 從前的日色變得慢 ...
    屋頂?shù)男∈[閱讀 152評(píng)論 0 0