使用這12個Git的訣竅與技巧來令你的版本控制經驗更加有用,
Git,一個分布式版本控制系統,它已經成為了開源世界的原始碼控制默認工具,在4月7號12歲了,但是使用Git中更另人沮喪的是,你需要了解多少才能讓你更有效的使用它,同時這也是使用Git中比較美妙的一件事,因為沒有什么比發現一個新的小技巧來簡化或提高你的作業流的效率更加令人快樂了,
為了紀念Git的12歲生日,這篇文章提供12個訣竅與技巧來讓你的Git經驗更加有用和強大,從一些你可能會忽視的基礎開始到一些真正的強大技巧!
1. 你的 ~/.gitconfig 檔案
在第一次用git命令來提交一個倉庫的修改,你可能會首先看到像下面這種內容:
Please tell me who you are.
Run
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
to set your account's default identity.
你可能還沒有意識到那些命令正在修改/.gitconfig檔案的內容,這個檔案就是Git存盤全域配置選項的檔案,通過你的/.gitconfig檔案你可要做很多事情,包括定義別名,永久的打開(或關閉)一些特定的命令選項,還可以修改Git如何作業的方面(例如:git diff使用哪個diff演算法,或者默認使用什么型別的的合并策略),你甚至可以按條件地基于路徑包含其他組態檔到一個倉庫!使用“man git-config”查看所有細節,
2. 你的倉庫的.gitconfig檔案
在之前的技巧中,你可能會想知道在git config 命令中的—global標識是做什么的,它告訴Git更新“global”配置,也就是~/.gitconfig發現的這個配置,當然,擁有一個全域的配置代表了一個本地配置,而且足夠肯定的是,如果你省略—global選項,git config 會更新這個倉庫自己的配置,這個組態檔存盤在.git/config,
在.git/config中設定的選項會推翻在~/.gitconfig檔案中的對應設定,因此,例如,如果你需要在一個特定的倉庫中使用一個不同的郵箱地址,你可以運行“git config user.email "[email protected]"”,然后,你在這個倉庫中提交會使用你單獨配置的這個郵箱地址,如果你使用一個作業的電腦在開源專案中作業,但是希望在這個專案中使用個人的郵箱地址,而其他在主Git配置中仍然使用作業郵箱,這一點是非常有用的,
在/.gitconfig中可以設定的任何東西,都可以在.git/config中設定來對這個倉庫做特定設定,在下面的這些技巧中,當我提到在你的/.gitconfig檔案中添加什么東西,同時也說明可以在特定的倉庫的.git/config中添加來設定那個選項,
3、別名
別名是你可以在你的~/.gitconfig檔案里做的另外一件事,他的作業原理就像shell命令列里的別名——設定一個新的命令名稱來呼叫一個或者多個其他的命令,這些命令通常包括一些特定的選項或標識,別名對于你經常使用的那些又長又復雜的命令列是非常有效的,
你可以使用git config命令來定義別名——例如,執行”git config —global —add alias.st status”命令后,會使得執行git st與執行git status做的是同樣的事情——然而,我發現當定義別名的時候,只需要直接在~/.gitconfig檔案里編輯通常會更加容易,
如果你選擇這么做,你會發現~/.gitconfig檔案就是一個INI檔案,INI是一種帶有特定段落的基礎鍵值對檔案格式,添加一個別名時,你將改變[alias]段落,例如:上面提到的定義相同的git st別名,需要添加下面這段代碼:
[alias]
st = status
(如果已經有了[alias]這個段落,只需要在這個段落中添加到第二行)
4. shell命令中的別名
別名不僅僅是運行其他Git子命令——你也可以定義別名,這些別名可以運行其他shell命令,這是一個很好的方法來處理一個重復的、罕見的、復雜的任務:一旦你已經想到第一次怎么做,那就使用一個別名保存這個命令,例如,我有幾個倉庫是我fork了一個開源專案,而且在本地做了一些修改,這些修改不用貢獻給這個專案,在專案的持續的開發的程序中我想保持最新的版本,同時保留我的本地修改,為了完成這個想法,我需要定期地從upstream倉庫中合并這些修改到我的fork——我定義一個別名“upstream-merge”來完成這個操作,定義如下:
upstream-merge = !"git fetch origin -v && git fetch upstream -v && git merge upstream/master && git push"
別名定義開始的這個“!”是告訴Git來通過shell運行這個命令,這個例子包括了運行一些git命令,但是使用這種方式定義別名可以運行任何shell命令,
(注意:如果你想復制我的upstream-merge別名,你將需要確認你有一個Git remote命名為upstream來指定這個你fork的upstream倉庫,你可以通過“git remote add upstream ”來添加一個,)
5. 可視化提交圖
如果你從事的是一個有很多分支活動的專案,有時可能很難掌握所有正在發生的作業以及它們之間的相關性,各種GUI工具可讓你弄清楚不同分支的概況以及在所謂的“提交圖”中提交記錄,例如,以下是我使用 GitLab 提交圖查看器進行可視化的一個存盤卡的部分截圖:

John Anderson, CC BY
如果你是專注于命令列的用戶,就可以不在多個工具之間切換導致分心,這個工具在命令列上實作了類似圖形界面的提交視圖,通過 -- graph 引數獲取 git 的記錄:

John Anderson, CC BY
下面的命令可以得到一樣的倉庫可視化片段:
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
--graph 選項將圖表添加到日志的左側, --abbrev-commit 存盤提交使用了 SHA 方法, --date=relative 運算式用相對的術語來表示日期,并且 --pretty 以 bit 格式處理自定義格式,我知道 git lg 的別名,它是我最常運行的10個命令之一,
6. 更優雅的強制推送(force-push)
有時,就跟你盡量避免使用它一樣困難的是,你會發現你需要運行 git push --force 來覆寫你倉庫的遠程副本上的歷史記錄,你可能已得到了一些反饋,他們會要求你進行互動式的變基(rebase),或者你可能已經搞砸了,并且希望隱藏證據,
當他人在倉庫的遠程副本的同一分支上進行改動后,會發生強制推送的風險,當你強制推送已重寫的歷史記錄時,某些提交將會丟失,這是 git push --force-with-lease 出現的原因 - 如果遠程分支已更新,它不會允許你執行強制推送,這將確保你不會丟棄他人的作業,
7. git add -N
你是否使用過git commit -a在一次行動中提交你所有未完成的修改,只有在你push完你的提交后才發現git commit -a忽略了新添加的檔案?解決這個問題你可以用git add -N(“通知”)來告訴Git你想把新添加的檔案包含在提交中在你第一次實際提交之前,
8. git add -p
一最佳的實踐為當使用Git時確保每個提交只包含一個邏輯更改--不管是修復一個bug還是(實作)一個新功能,然而, 有時當你作業 ,會在你的倉庫中出現一個以上的修改 提交 ,你怎么樣把事情分開,使每個提交只包含適當的修改呢?git add --patch來解救!
這個標志將會使git add命令查看你作業副本中所有的變更,詢問你是否愿意將它提交,跳過,或者推遲決定(還有其他一些更強大的選項,你可以通過在運行這命令后選擇?來查看),git add -p是一個神奇的工具來生產結構良好的提交,
9. git checkout -p
與 git add -p類似,git checkout命令將使用 --patch 或 -p 選項,這會使 git 在本地作業副本中展示每個“大塊”的改動,并允許丟棄對應改動 —— 簡單地說就是恢復本地作業副本到你改變之前的狀態,
某些場景下這非常有用,例如,在你跟蹤一個 bug 時引入了一堆除錯日志陳述句,在修正了這個 bug 之后,你可以先使用 git checkout -p 洗掉所有新加的除錯日志,之后使用 git add -p 來添加 bug 修復,沒有比組合一個極好的、結構良好的提交更令人滿意的了
10. Rebase with command execution
有些專案有一條規則,即存盤庫中的每個提交都必須處于可作業狀態 - 也就是說,在每次提交時,代碼應該是可編譯的,或運行測驗套件應該不會失敗的,當你在某分支上作業時間長時,但如果你最終因為某種原因需要rebase時,那么跳過每個變基后的提交以確保你沒有意外引入一個中斷是有些冗長乏味的,
幸運的是,git rebase已經支持了-x或--exec選項,git rebase -x 將在每次提交應用到rebase后運行該命令,因此,例如,如果你有一個專案,其中npm run tests會運行你的測驗套件,那么在rebase期間應用每次提交后,git rebase -x npm run tests將會運行測驗套件,這使你可以查看測驗套件是否在任何變基后的提交中有失敗情況,因此你可以確保測驗套件在每次提交時仍能通過,
11. 基于時間修改的指南
很多Git子命令都接受一個修正的引數來決定命令作用于倉庫的哪個部分,可能是某次特定的提交的 sha1 值,或者一個分支的名稱,又或者是一個符號性的名稱如 HEAD(代表當前檢出分支最后一次的提交),除了這些簡單的形式以外,你還可以附加一個指定的日期或時間作為引數,表示“這個時間的參考”,
這個功能在某些時候會變得十分有用,比如當你處理最新出現的 bug,自言自語道:“這個功能明明昨天還是好好的,到底又改了些什么”,不用盯著滿屏的 git 日志的輸出試圖弄清楚什么時候更改了提交,您只需運行 git diff HEAD@{yesterday},會看到從昨天以來的所有修改,這也適用于較長的時間段(例如 git diff HEAD@{'2 months ago'}) ,以及一個確切的日期(例如git diff HEAD@{'2010-01-01 12:00:00'}),
您還可以將這些基于日期的修改引數與使用修正引數的任何 Git 子命令一起使用,在 gitrevisions 手冊頁中有關于具體使用哪種格式的詳細資訊,
12. 全知的 reflog
你是不是試過在 rebase 時干掉過某次提交,后來又發現你需要保留這次提交的一些東西?你可能覺得這些提交的東西已經永遠找不回來了,只能從頭再來了,其實不然,但如果你在本地作業副本中提交了,提交就會進入到 "參考日志" ,你仍然可以訪問到,
運行 git reflog 將在本地作業副本中顯示當前分支的所有活動的串列,并為您提供每個提交的 SHA1 值,一旦發現你 rebase 時放棄的那個提交,你可以運行 git checkout 來檢出該次提交,復制好你需要的資訊,然后再運行 git checkout HEAD 回傳到分支最新的提交去,
希望這些技巧中至少有一個能教你一些關于 Git 的新知識,Git 已經 12 歲了,在這個持續創新,不斷添加新特性的專案里,你最喜歡哪個技巧?
原文:https://opensource.com/article/18/4/git-tips
譯文:https://www.oschina.net/translate/12-git-tips-gits-12th-birthday
關注公眾號Java技術堆疊回復"面試"獲取我整理的2020最全面試題及答案,
推薦去我的博客閱讀更多:
1.Java JVM、集合、多執行緒、新特性系列教程
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
4.Java、后端、架構、阿里巴巴等大廠最新面試題
覺得不錯,別忘了點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/149778.html
標籤:Java
