Git 少用 Pull 多用 Fetch 和 Merge

轉自:http://www.oschina.net/translate/git-fetch-and-merge??

---------------------------------------------------------------------------------

本文有點長而且有點亂,但就像Mark Twain?Blaise Pascal的笑話里說的那樣:我沒有時間讓它更短些。在Git的郵件列表里有很多關于本文的討論,我會盡量把其中相關的觀點列在下面。

我最常說的關于git使用的一個經驗就是:

不要用git pull,用git fetch和git merge代替它。

git pull的問題是它把過程的細節都隱藏了起來,以至于你不用去了解git中各種類型分支的區別和使用方法。當然,多數時候這是沒問題的,但一旦代碼有問題,你很難找到出錯的地方。看起來git pull的用法會使你吃驚,簡單看一下git的使用文檔應該就能說服你。

將下載(fetch)和合并(merge)放到一個命令里的另外一個弊端是,你的本地工作目錄在未經確認的情況下就會被遠程分支更新。當然,除非你關閉所有的安全選項,否則git pull在你本地工作目錄還不至于造成不可挽回的損失,但很多時候我們寧愿做的慢一些,也不愿意返工重來。

Andy

Andy
翻譯于 3年前

4人頂

頂?翻譯的不錯哦!

分支(Branches)

在說git pull之前,我們需要先澄清分支的概念(branches)。很多人像寫代碼似的用一行話來描述分支是什么,例如:

  • 準確而言,分支的概念不是一條線,而類似于開發中的有向無環圖
  • 分支類似于一個重量級的大對象集合。

我認為你應該這樣來理解分支的概念:它是用來標記特定的代碼提交,每一個分支通過SHA1sum值來標識,所以對分支進行的操作是輕量級的--你改變的僅僅是SHA1sum值。

Andy

Andy
翻譯于 3年前

3人頂

頂?翻譯的不錯哦!

這個定義或許會有意想不到的影響。比如,假設你有兩個分支,“stable” 和 “new-idea”, 它們的頂端在版本 E 和 F:

  A-----C----E ("stable")\B-----D-----F ("new-idea")

所以提交(commits) A, C和 E 屬于“stable”,而?A, B, D 和 F 屬于 “new-idea”。如果之后你用下面的命令?將“new-idea”?merge 到 “stable” :

    git checkout stable   # Change to work on the branch "stable"git merge new-idea    # Merge in "new-idea"

…那么你會得到這個:

  A-----C----E----G ("stable")\             /B-----D-----F ("new-idea")

要是你繼續在“new idea” 和“stable”分支提交, 會得到:

  A-----C----E----G---H ("stable")\             /B-----D-----F----I ("new-idea")

因此現在A, B, C, D, E, F, G 和 H 屬于 “stable”,而A, B, D, F 和 I 屬于 “new-idea”。

當然了,分支確實有些特殊的屬性——其中最重要的是,如果你在一個分支進行作業并創建了一個新的提交(commits),該分支的頂端將前進到那個提交(commits)。這正是你所希望的。當用git merge?進行合并(merge)的時候,你只是指定了要合并到當前分支的那個并入分支,以及當前分支的當前進展。

super0555

super0555
翻譯于 3年前

3人頂

頂?翻譯的不錯哦!

另一個表明使用分支會有很大幫助的觀點的常見情形是:假設你直接工作在一個項目的主要分支(稱為“主版本”),當你意識到你所做的可能是一個壞主意時已經晚了,這時你肯定寧愿自己是工作在一個主題分支上。如果提交圖看起來像這樣:

   last version from another repository|vM---N-----O----P---Q ("master")

那么你把你的工作用下面的一組命令分開做(如圖顯示的是執行它們之后所更改的狀態):

  git branch dubious-experimentM---N-----O----P---Q ("master" and "dubious-experiment")git checkout master# Be careful with this next command: make sure "git status" is# clean, you're definitely on "master" and the# "dubious-experiment" branch has the commits you were working# on first...git reset --hard <SHA1sum of commit N>("master")M---N-------------O----P---Q ("dubious-experiment")git pull # Or something that updates "master" from# somewhere else...M--N----R---S ("master")\O---P---Q ("dubious-experiment")

這是個看起來我最終做了很多的事情。

趙亮-碧海情天

趙亮-碧海情天
翻譯于 3年前

4人頂

頂?翻譯的不錯哦!

分支類型

分支這個術語不太容易理解,而且在git的開發過程中發生了很多變化。但簡單來說git的分支只有兩種:

a)“本地分支(local branches)” ,當你輸入“git branch”時顯示的。例如下面這個小例子:

       $ git branchdebianserver* master
b)“遠程跟蹤分支(Remote-tracking branches)” ,當你輸入“git branch -r”是顯示的,如:

?

       $ git branch -rcognac/masterfruitfly/serverorigin/albertorigin/antorigin/contriborigin/cross-compile
從上面的輸出可以看到,跟蹤分支的名稱前有一個“遠程的”標記名稱(如?:origin, cognac, fruitfly)后面跟一個“/”,然后遠程倉庫里分支的真正名稱。(“遠程名稱”是一個代碼倉庫別名,和本地目錄或URL是一個含義,你可以通過"git remote"命令自由定義額外的“遠程名稱”。但“git clone”命令默認使用的是“origin”這個名稱。)
Andy

Andy
翻譯于 3年前

4人頂

頂?翻譯的不錯哦!

如果你對分支在本地是如何存儲感興趣的話,看看下面文件:?
  • ? .git/refs/head/[本地分支]
  • ? .git/refs/remotes/[正在跟蹤的分支]
兩種類型的分支在某些方面十分相似-它們都只是在本地存儲一個表示提交的SHA1校驗和。(我強調“本地”,因為許多人看到"origin/master" 就認為這個分支在某種意義上說是不完整的,沒有訪問遠端服務器的權限- 其實不是這種情況。)
不管如何相似,它們還是有一個特別重大的區別:?
  • ? 更改遠端跟蹤分支的安全方法是使用git fetch或者是作為git-push副產品,你不能直接對遠端跟蹤分支這么操作。相反,你總得切換到本地分支,然后創建可移動到分支頂端的新提交 。
因此,你對遠端跟蹤分支最多能做的是下面事情中的一件:?
  • ?使用git fetch 更新遠端跟蹤分支
  • ?合并遠端跟蹤分支到當前分支
  • ?根據遠端跟蹤分支創建本地分支
幾點人

幾點人
翻譯于 3年前

2人頂

頂?翻譯的不錯哦!

基于遠程跟蹤分支創建本地分支

如果你想基于遠程跟蹤分支創建本地分支(在本地分支上工作),你可以使用如下命令:git branch –track或git checkout –track -b,兩個命令都可以讓你切換到新創建的本地分支。例如你用git branch -r命令看到一個遠程跟蹤分支的名稱為“origin/refactored”是你所需要的,你可以使用下面的命令:

    git checkout --track -b refactored origin/refactored
在上面的命令里,“refactored”是這個新分支的名稱,“origin/refactored”則是現存遠程跟蹤分支的名稱。(在git最新的版本里,例子中‘-track’選項已經不需要了,如果最后一個參數是遠程跟蹤分支,這個參數會被默認加上。)
Andy

Andy
翻譯于 3年前

2人頂

頂?翻譯的不錯哦!

“–track”選項會設置一些變量,來保持本地分支和遠程跟蹤分支的相關性。他們對下面的情況很有用:

  • git pull命令下載新的遠程跟蹤分支之后,可以知道合并到哪個本地分支里
  • 使用git checkout檢查本地分支時,可以輸出一些有用的信息:
    Your branch and the tracked remote branch 'origin/master'have diverged, and respectively have 3 and 384 differentcommit(s) each.
或者:
    Your branch is behind the tracked remote branch'origin/master' by 3 commits, and can be fast-forwarded.
允許使用的配置變量是:“branch.<local-branch-name>.merge”和“branch.<local-branch-name>.remote”,但通常情況下你不用考慮他們的設置。
Andy

Andy
翻譯于 3年前

2人頂

頂?翻譯的不錯哦!

當從遠程代碼倉庫創建一個本地分支之后,你會注意到,“git branch -r”能列出很多遠程跟蹤分支,但你的電腦上只有一個本地分支,你需要給上面的命令設置一個參數,來指定本地分支和遠程分支的對應。

有一些術語上的說法容易混淆需要注意一下:“track”在當作參數"-track"使用時,意思指通過本地分支對應一個遠程跟蹤分支。在遠程跟蹤分支中則指遠程代碼倉庫中的跟蹤分支。有點繞口。。。
下面我們來看一個例子,如何從遠程分支中更新本地代碼,以及如何把本地分支推送到一個新的遠程倉庫中。
Andy

Andy
翻譯于 3年前

3人頂

頂?翻譯的不錯哦!

從遠端倉庫進行更新

如果我想從遠端的源倉庫更新到本地的代碼倉庫,可以輸入“git fetch origin”的命令,該命令的輸入類似如下格式:

  remote: Counting objects: 382, done.remote: Compressing objects: 100% (203/203), done.remote: Total 278 (delta 177), reused 103 (delta 59)Receiving objects: 100% (278/278), 4.89 MiB | 539 KiB/s, done.Resolving deltas: 100% (177/177), completed with 40 local objects.From ssh://longair@pacific.mpi-cbg.de/srv/git/fiji3036acc..9eb5e40  debian-release-20081030 -> origin/debian-release-20081030* [new branch]      debian-release-20081112 -> origin/debian-release-20081112* [new branch]      debian-release-20081112.1 -> origin/debian-release-20081112.13d619e7..6260626  master     -> origin/master
最重要的是這兩行:
     3036acc..9eb5e40  debian-release-20081030 -> origin/debian-release-20081030* [new branch]      debian-release-20081112 -> origin/debian-release-20081112
第一行表明遠端的origin/debian-release-20081030分支的提交(commit)ID已經從3036acc更新為9eb5e40。箭頭前的部分是遠端分支的名稱。第二行是我們采取的動作,創建遠程跟蹤分支(如果遠程倉庫有新的tags,git fetch也會一并下載到本地)。
Andy

Andy
翻譯于 3年前

2人頂

頂?翻譯的不錯哦!

前面那些行顯示出“git fetch”命令會將哪些文件下載到本地,這些文件一旦下載到本地之后,就可以在本地進行任意操作了。

“git fetch”命令執行完畢之后,還不會立即將下載的文件合并到你當前工作目錄里,這就給你了一個選擇下一步操作的機會,要是想將從遠程分支下載的文件更新到你的工作目錄里,你需要執行一個“合并(merge)”操作。例如,我當前的本地分支為”master“(執行git checkout master后),這時我想執行合并操作:

    git merge origin/master
(?幾句題外話:合并的時候有可能你還沒有對遠程分支提交過任何的更改,或者可能是一個復雜的合并。)
Andy

Andy
翻譯于 3年前

3人頂

頂?翻譯的不錯哦!

如果你只是想看看本地分支和遠程分支的差異,你可以使用下面的命令:

git diff master origin/master
單獨進行下載和合并是一個好的做法,你可以先看看下載的是什么,然后再決定是否和本地代碼合并。而且分開來做,可以清晰的區別開本地分支和遠程分支,方便選擇使用。
Andy

Andy
翻譯于 3年前

2人頂

頂?翻譯的不錯哦!

把你的變更推送到一個遠程倉庫

如何通過其他的方式呢? 假設你對 “experimental”分支做了變更并且希望把他push到"origin"遠程倉庫中去. 你可以這樣做:

?

1

git push origin experimental

?

你可能將會收到:遠程倉庫無法fast-forward該分支的錯誤信息, 這將意味著可能有別人push了不同的變更到了這個分支上.所以,你需要fetch和merge別人的變更并再次嘗試push操作.

_Raymond

_Raymond
翻譯于 3年前

2人頂

頂?翻譯的不錯哦!

擴展閱讀: 如果這個分支在遠程倉庫里對應不同的名稱(如:experiment-by-bob),你應該這么做:?
git push origin experimental:experiment-by-bob

在舊版本的git里,如果“experiment-by-bob”不存在,命令應該這么寫:?
      git push origin experimental:refs/heads/experiment-by-bob

這樣會首先創建遠程分支。但git 1.6.1.2應該就不用這么做了。參加下面Sitaram’s的評論。?
?如果本地分支和遠程分支名稱相同,不需要特殊說明系統將會自動創建這個分支,就像常規的git push操作一樣。?

在實際應用中,保持名稱相同可以減少混淆,因此“本地名稱和遠程名稱”作為“refspec”參數,我們不會進行更多的討論。

git push的操作不會牽扯遠程跟蹤分支(origin/experimental),只有在你下次進行git fetch時才會被更新。

上面這個說法不對,根據Deskin Miller的評論糾正:當推送到對應的遠程分支后,你的遠程跟蹤分支就會被更新。

Andy

Andy
翻譯于 3年前

2人頂

頂?翻譯的不錯哦!

?

為什么不用 git 的 pull?

雖然?git pull?大部分時候是好的,特別是如果你用CVS類型的方式使用Git時,它可能正適合你。然而,如果你想用一個更地道的方式(建立很多主題分支,當你需要時隨時改寫本地歷史,等等)使用Git,那么習慣把?git fetch?和?git merge?分開做會有很大幫助。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537807.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537807.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537807.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IDEA生成可運行jar包

方式1: maven打包 maven 包中添加如下配置 <build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><appendAssemblyId>false</appendAssemblyId><descriptorRefs><descriptorRef&…

linux packet socket,linux Packet socket (1)簡單介紹

本文主要來自于linux自帶的man packet手冊&#xff1a;http://man7.org/linux/man-pages/man7/packet.7.html平時常常使用的INET套接字提供的是7層的抓包能力&#xff0c;抓上來的data直接就是tcp或者udp的payload&#xff0c;無需關心L3和L4的頭部信息。Packet套接字提供的是L…

TortoiseGit 修改密碼

當TortoiseGi默認設置了憑證助手為“管理器-所有windows用戶”&#xff0c;每次向遠程git推送時&#xff0c;都會去windows的憑證管理器里讀取值&#xff0c;然后推送。 如果密碼修改了&#xff0c;或者密碼不小心輸入錯了&#xff0c;每次提交都會報錯&#xff1a;HTTP Basic:…

linux系統常見操作,Linux系統基本操作

我們可以認為Linux是一套自由使用的類Unix操作系統&#xff0c;與Windows相比較而言&#xff0c;Linux具有安全、開源、穩定等特點。下面我來介紹Linux中一些的登錄登出基本操作。1. 啟動系統通常LILO是安裝在MBR上的&#xff0c;計算機啟動后&#xff0c;MBR上的程序被執行&am…

字符串常見處理

mystr hello world itcast and itcastcpps mystr.find(hello)print(s)ind mystr.index(world)print(ind)cou mystr.count(c)print(cou)rep mystr.replace(c,)print(rep)spl mystr.split( )print(spl)轉載于:https://www.cnblogs.com/zxt-cn/p/9714841.html

git 無法訪問

git分2種訪問方式&#xff1a;ssh&#xff0c;https ssh模式&#xff0c;需要在github或gitlab上配置公鑰&#xff0c;本地要生成秘鑰。 舉例&#xff1a; 公司使用gitlab 張工需要訪問公司李工的代碼庫。 步驟&#xff1a; 1、李工要在gitlab他的項目里&#xff0c;給張…

c語言編程統計單詞的個數,使用c語言如何統計單詞個數

使用c語言如何統計單詞個數發布時間&#xff1a;2020-04-21 13:58:58來源&#xff1a;億速云閱讀&#xff1a;207作者&#xff1a;小新使用c語言如何統計單詞個數&#xff1f;相信有很多人都不太了解&#xff0c;今天小編為了讓大家更加了解Golang&#xff0c;所以給大家總結了…

10 種保護 Spring Boot 應用的絕佳方法

Spring Boot大大簡化了Spring應用程序的開發。它的自動配置和啟動依賴大大減少了開始一個應用所需的代碼和配置量&#xff0c;如果你已經習慣了Spring和大量XML配置&#xff0c;Spring Boot無疑是一股清新的空氣。 Spring Boot于2014年首次發布&#xff0c;自那以后發生了很多變…

zkServer.cmd 閃退

調用 zkEnv.cmd 查看下 zkEnv.cmd 在\conf下復制zoo_sample.cfg 重命名為 zoo.cfg 再運行&#xff0c;成功

c語言單字符輸入和輸出函數分別為,第03章單元總練習-實訓-知識拓展.doc

第03章單元總練習-實訓-知識拓展《C語言程序設計》單元總結單元練習實訓指導知識拓展第三章 最簡單的C程序設計——順序結構設計班級:姓名:學號:單元總結提升本單元中&#xff0c;核心內容有C語言中基本的數據類型、常量和變量、運算符和表達式以及算法的概念。通過本單元的學習…

那些你不知道的 getClientRects()

1.getClientRects()。是可以獲取內聯元素的內容有多少行 最近一個交互&#xff0c;在限定文字展現是5行&#xff0c;超過5行&#xff0c;則在后面添加。。。展開。如果沒有展開二字&#xff0c;我們一般用css就能完成了。但是為了交互更人性化 text-overflow: -o-ellipsis-last…

idea統計代碼行數

使用統計代碼插件&#xff0c;可以統計代碼行數。安裝插件 Statistic。&#xff08;這個最好用&#xff09; File----settiing---plugins---browse repositories 重啟idea后&#xff0c;底部會多一個 Statistic 點擊刷新&#xff0c;行數就出來了。看最后的 Total

數據結構計算c語言數據步驟,數據結構C語言版視頻教程-介紹各種最常用的數據結構 分析各種數據結構運算算法的實現過程-電腦網絡視頻-星火視頻教程 21edu8.com...

這部數據結構C語言版視頻教程結構清晰&#xff0c;實例豐富&#xff0c;具有很強的操作性和實用性。 它主要為大家介紹各種最常用的數據結構&#xff0c;以及從編程角度出發&#xff0c;分析各種數據結構運算算法的實現過程。數據結構是計算機存儲、組織數據的方式。數據結構是…

極光推送小結 - iOS

此次即友盟分享小結(友盟分享小結 - iOS)之后對推送也進行了一版優化.此次分享內容依然基于已經成功集成 SDK 后 code 層級部分. 注:此次分享基于 SDK 3.1.0,若版本相差較大,僅供參考. 極光推送官方文檔: https://docs.jiguang.cn/jpush/guideline/intro/ 首先,為分享單獨創建了…

word去除所有的空行

申請軟著時&#xff0c;需要復制源代碼到word里。每行代碼不能有換行&#xff0c;要緊湊的80頁代碼。每頁要50~55行代碼。 字體可設置為&#xff1a;宋體&#xff0c;5號&#xff0c;行間距固定值12。 演示實例 去除下面word代碼里的空行 第一步&#xff1a; word顯示隱藏的…

c語言Wndproc未定義,為什么我的老是未定義

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓這是源代碼#includeLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow){static TCHAR szAppName[] TEXT("HelloWin&qu…

spark on yarn

2019獨角獸企業重金招聘Python工程師標準>>> spark on yarn 軟件安裝 當前環境 hadoop環境搭建參考&#xff1a;hadoop集群安裝 hadoop2.6spark-2.2.0-bin-hadoop2.6.tgzscala-2.11.12安裝scala tar -zxvf scala-2.11.12.tgz vi /etc/profile 添加以下內容 export S…

如何查看SQL Server2000執行過的SQL語句

SQLServer事件探查器可以完整記錄SQL服務器執行過的SQL語句以及存儲過程等 下面是SQLServer事件探查器的使用方法&#xff1a; 1. 打開SQL Server 企業管理器。 2. 從“工具”菜單選擇“事件探查器”。 3. 當“事件探查器”主界面打開后&#xff0c;從“文件”菜單選擇“新跟蹤…

c語言鏈表不帶頭節點的排序,不帶頭結點的單向鏈表排序——插入排序(C語言)...

LinkList* LinkListInsertSort(LinkList* pHead){LinkList *pFirst (LinkList *)NULL; /* 原鏈表剩下未排序節點的頭指針 */LinkList *pCurrInsert (LinkList *)NULL; /* 無序鏈表中當前待插入節點 */LinkList *pPrev (LinkList *)NULL; /* 有序鏈表中插入位置的前一個節點 …

免費字體

若不想字體版權有問題&#xff0c;可以參考以下幾種完全免費的字體&#xff1a; 方正&#xff1a;方正黑體、方正書宋、方正仿宋、方正楷體 思源&#xff1a;思源黑體、思源柔黑體、思源宋體 站酷&#xff1a;站酷酷黑體、站酷高端黑體、站酷快樂體、站酷意大利體 。