了解 Linux 常見命令
在使用 git 前,建議事先熟悉一些常見的 bash 命令
進入xxx目錄
$ cd xxx
移動
$ mv [old-name] [new-name]
刪除單個文件
$ rm test.txt
刪除當前目錄下的一個文件
當前目錄下建立文件夾
$ mkdir [folder-name]
顯示當前目錄
$ pwd
查看該目錄下的文件和文件夾
$ ls -al
查看該目錄下的文件和文件夾包含隱藏目錄
$ ls -ah
配置 config
可以通過git config rexx.aa.bb cc
, git config aa.bb.cc 'dd'
進行設置。
每一條命令都在.git/config文件中添加一行。如果該遠程部分不存在,那么你發出的第一條命令將在該文件中為它創建。
[rexx "aa"]
bb = cc
[aa "bb"]
cc = dd
- git config -l, --list 列舉完整配置文件內容
- git config --list --local 列舉出 local 所有配置
- git config --list --global 列舉出 global 所有配置
- git config --list --system 列舉出 system 所有配置
查看配置 config 文件
配置Git的時候,加上 --global
是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用。每個倉庫的 Git 配置文件都放在.git/config
文件中。因為配置文件只是簡單的文本文件,所以可以通過 cat 命令來查看其內容, 也可以通過你最喜歡的文本編輯器來編輯它。
$ cat .git/config
別名就在[alias]
后面,要刪除別名,直接把對應的行刪掉即可。
而當前用戶的 Git 配置文件放在用戶主目錄下的一個隱藏文件.gitconfig
中:
$ cat .gitconfig
[alias]
co = checkout
ci = commit
br = branch
st = status
[user]
name = Your Name
email = your@email.com
初始化 init
git init 在當前目錄初始化倉庫
git init [path] 初始化倉庫
git init [path] --bare 初始化一個裸倉庫
Git不關心你是從一個完全空白的目錄還是由一個裝滿文件的目錄開始的。在這兩種情況下,將目錄轉換到Git版本庫的過程是一樣的。
細心的讀者可以發現在 init 之后,目錄下多了一個.git 的目錄,這個目錄是 Git 來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄里面的文件,不然改亂了,就把 Git 倉庫給破壞了。
PS:如果你沒有看到 .git 目錄,那是因為這個目錄默認是隱藏的
一個Git版本庫要么是一個裸(bare)版本庫,要么是一個開發(非裸)
(development, nonbare)版本庫。開發版本庫用于常規的日常開發。它保持當前分支的概念,并在工作目錄中提供檢出當前分支的副本。相反,一個裸版本庫沒有工作目錄,并且不應該用于正常開發。裸版本庫也沒有檢出分支的概念。裸版本庫可以簡單地看做git目錄的內容。換句話說,不應該在裸版本庫中進行提交操作。
按照慣例,裸版本庫名有個.git 后綴。這不是必需的,但認為這是最佳實踐。
查看工作區狀態 status
git status
-s, --short
Give the output in the short-format.
git status 命令目前是否有暫存的變更需要提交,工作目錄是否是干凈(clean)的等信息。 經常檢查當前狀態是個好習慣
工作目錄干凈意味著工作目錄里不包含任何與版本庫中不同的未知或者更改過的文件。
查看幫助 help
$ git help <command>
/ $ git <command> --help
獲取幫助
-w, --web
以網頁(HTML)格式顯示命令的手冊頁
文件至暫存區 add
這是個多功能命令,根據目標文件的狀態不同,此命令的效果也不同:可以用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區,還能用于合并時把有沖突的文件標記為已解決狀態等
git add [filename1] [filename2] ...
//可以一次提交很多文件
例如
$ git add src/com/abc/MainActivity.java
add單個文件
$ git add src/
add單個文件夾
$ git add .
添加對應目錄下所有文件和文件夾
git add -A 提交所有變化
git add . 提交新文件(new)和被修改(modified)文件,不包括被刪除(deleted)文件
git add -u 提交被修改(modified)和被刪除(deleted)文件,不包括新文件(new)
例如本次刪除了一個已被 git 管理的文件 rm 1.txt
則可以通過 git add -u
將此次變更提交至暫存區。也可以鍵入 git rm 1.txt
或者 git add 1.txt
達到同樣的目的。
git-diff - Show changes between commits
$ git diff
git diff會顯示工作目錄和索引之間的差異。
$ git diff commit
會顯示工作目錄和給定提交間的差異。常見的一種用法是用HEAD或者一個特定的分支名作為commit
$ git diff --cached commit
(或 --staged
Git 1.6.1 及更高版本上允許使用,效果相同), 顯示索引中的變更中和給定提交中的變更之間的差異。如果省略 commit這一項,則默認為HEAD,使用HEAD,該命令會顯示下次提交會如何修改當前分支。
注:如果拼接上 -- [filename] 表示比較特定文件的差異。
可以用 git diff 的這兩種形式引導你完成暫存變更的過程。最初, git diff顯示所有修改的大集合, --cached則是空的。而當暫存時,前者的集合會收縮,后者會增大。如果所有修改都暫存了并準備提交,--cached將是滿的,而git diff則什么都不顯示。
$ git diff [<commit-id1>] [<commit-id2>]
比較兩個commit-id之間的差異
$ git diff [<commit-id1>] [<commit-id2>] -- abc.txt edf.md
比較兩個commit-id之間指定文件的差異
舉例:為了查看兩個版本之間的差異,使用兩個提交的全ID名并且運行 git diff
$ git diff 9da581d910c9c4ac93557ca4859e767f5caf5169 \
ec232cddfb94e9dfd5b5855af8ded7f5eb5c9ed6
刪除 rm
git rm 命令自然是與 git add 相反的命令。它會在版本庫和工作目錄中同時刪除文件。
注意:git rm 也是一條對索引進行操作的命令,所以它對沒有添加到版本庫或索引中的文件是不起作用的; Git必須先認識到文件才行。
$ git rm
從暫存區和工作區刪除, 直接做了本地 rm 和 add/rm 到暫存區的操作.
$ git rm --cached readme.txt
僅從暫存區刪除,和add 命令相對.
但仍希望保留在當前工作目錄中。換句話說,僅是從跟蹤清單中刪除。比如一些大型日志文件或者一堆 .a 編譯文件,不小心納入倉庫后,要移除跟蹤但不刪除文件,以便稍后在 .gitignore
文件中補上.
$ git rm $(git ls-files --deleted)
: 刪除所有被跟蹤, 但是在工作區總被刪除的文件
移動 | 重命名 mv
$ git mv [oldFile] [newFile]
其實,運行 git mv 就相當于運行了下面三條命令:
mv README.txt README
git rm README.txt
git add README
Git 在對文件的移動操作上與其他同類系統不同,它利用一個基于兩個文件版本內容相似度的機制。
Git 的強大功能是即使經歷過重命名,也仍然能保留對文件歷史記錄的追蹤。
在使用 git --follow log 選項會讓 Git 在日志中回溯并找到內容相關聯的整個歷史記錄。
示例
$ git Log --follow README
還原工作區文件 | 切換分支 checkout
$ git checkout -- <file>...
(to discard changes in working directory)
將文件內容從暫存區復制到工作目錄
舉例git checkout -- readme.txt
意思就是,把readme.txt文件在工作區的修改全部撤銷,
這里有兩種情況:
一種是 readme.txt 自修改后還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;
一種是 readme.txt 已經添加到暫存區后,又作了修改,現在,撤銷修改就回到添加到暫存區后的狀態。
舉例
git checkout -- README.MD
git checkout -- .
git checkout HEAD -- .
在Git中,HEAD 始終指向當前分支的最近提交。當切換分支時, HEAD 會更新為指向新分支的最近提交。
在同一代提交中,插入符號^是用來選擇不同的父提交的。給定一個提交C, C^1是其第一個父提交, C^2是其第二個父提交, C^3是其第三個父提交.
波浪線~用于返回父提交之前并選擇上一代提交。同樣,給定一個提交C, C~1是其第一個父提交, C-2是其第一個祖父提交, C-3是第一個曾祖父提交。當在同一代中存在多個父提交時,緊跟其后的是第一個父提交的第一個父提交。你可能會注意到,C^1和C~1都指的是C的第一個父提交,兩個名字都是對的, 如圖所示。
總之,就是讓這個文件回到最近一次 git commit 或 git add 時的狀態。
這條命令有些危險,所有對文件的修改都沒有了,因為我們剛剛把之前版本的文件復制過來重寫了此文件。所以在用這條命令前,請務必確定真的不再需要保留剛才的修改。
針對分支
$ git checkout -
切換到上一個分支
$ git checkout [commit id]
表示當前 HEAD 指針指向某一個commit id, commid可以是分支名稱,表示切換到該分支.
我們發現在使用 checkout 操作工作區的文件時,通過“裸雙破折號”的約定來分離一系列參數。因此建議操作文件的時候建議顯式加上 -- 。
# Checkout the tag named "main.c"
$ git checkout main.d
# Checkout the file named "main.c"
$ git checkout -- main.c
提交在暫存區的修改 commit
$ git commit -m 'initial project version'
注意: Git 只不過暫存了你運行 git add 命令時的版本, 而非當前工作目錄中的版本。
每次修改,如果不add到暫存區,那就不會加入到commit中
跳過使用暫存區域
$ git commit -a/--all -m 'added new benchmarks'
跳過使用暫存區域的方式,只要在提交的時候,給git commit 加上 -a 選項,Git 就會自動把所有已經跟蹤過的文件暫存起來一并提交,從而跳過 git add 步驟, 如果有未跟蹤的文件還是需要先進行 add。
對于普通的git commit命令, git commit--amend
會彈出編輯器會話,可以在里面修改提交消息。
git commit --amend
也可以直接修改最后一次提交的注釋
$ git commit --amend -m "someMessage"
git commit --amend 事實上可以作為新提交的一部分添加或刪除文件。要做到這一點,先改正工作目錄中的文件。更正錄入錯誤然后根據需要添加或刪除文件。跟任何提交一樣,使用命令更新索引,如git add或git rm。然后發出git commit --amend命令。
--amend 這條命令還可以編輯提交的元信息。例如,通過指定--author可以改變提交的作
者。git commit -amend--author "Bob Miller <kbobgexample.com"
查看提交歷史 log
git log
# 等價于
git log HEAD
-num 參數表示我們只想看到num行記錄.
-p 按補丁格式顯示每個更新之間的差異。
--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 一行顯示
--author 【貢獻者名字】
--log --graph 圖示法顯示提交歷史
--reverse 提交版本默認是按照時間倒序排序,如果需要正序可以加上該參數
查看命令歷史 git reflog
git reflog
查看命令歷史
重置 HEAD 指針到特殊狀態| reset 命令
暫存區可以類比為加入購物車.
取消已經暫存的文件, 與 add 相對
$ git reset
所有當前暫存區的內容, 和 HEAD保持一致
$ git reset HEAD
同上
$ git reset HEAD <file>...
同上, 取消暫存區部分文件
$ git reset HEAD -- <file>...
同上
- 將當前分支回退到某個歷史版本
git reset commit-id
$ git reset --mixed commit_id
【默認】它將重置HEAD到另外一個commit,并且重置 index 以便和 HEAD 相匹配,但是也到此為止。working copy不會被更改。
$ git reset --soft commit_id
$ git reset --hard commit_id
--soft會將 HEAD 引用指向給定提交。索引和工作目錄的內容保持不變。這個版本的命令有“最小”影響, 只改變一個符號引用的狀態使其指向一個新提交。
--mixed 會將HEAD指向給定提交。索引內容也跟著改變以符合給定提交的樹結構,但是工作目錄中的內容保持不變。這個版本的命令將索引變成你剛剛暫存該提交全部變化時的狀態,它會顯示工作目錄中還有什么修改。
注意, --mixed是git reset的默認模式。
--hard 這條命令將HEAD引用指向給定提交。索引的內容也跟著改變以符合給定提交的樹結構。此外,工作目錄的內容也隨之改變以反映給定提交表示的樹的狀態。
當改變工作目錄的時候,整個目錄結構都改成給定提交對應的樣子。做的修改都將丟失,新文件將被刪除。在給定提交中但不在工作目錄中的文件將恢復回來。
例如:
例如回退到上個版本git reset --hard HEAD^
reset 和 checkout 的差異
推薦一個學習 git 的網站
https://learngitbranching.js.org/
重置關卡 reset
查看答案 show solution
參考
Git版本控制管理(第2版)-異步社區
https://www.epubit.com/bookDetails?id=N8405