2014-01-26 114 views
3

我有幾十個回購,我的腳本應該更新他們,如果發生任何差異,新提交,新標籤,新分支。在我的情況下,抓取數十個回購緩慢,我想知道是否有任何快速命令可以滿足我的要求。如何知道本地回購與遠程回購不同,不需要取回?

+0

使用diff命令 – 2014-01-26 10:13:53

+0

自動更新對實時服務器不利 – exussum

+1

如果沒有'fetch','git'不知道遠程存儲庫的狀態。任何不執行'fetch'的解決方案(例如,針對完整遠程URL的'diff')至少與'fetch'一樣慢,因爲它仍然需要檢索遠程倉庫的狀態。 – lanzz

回答

3

可以使用git ls-remote管道命令來獲取遙控器的狀態,不取。

在這裏,我們使用git本身作爲輕量級數據庫,以跟蹤遠程的狀態。

將以下內容放入腳本中;您可以稍後啓用它作爲git別名shell函數以方便使用。在你的回購裏面運行。

REMOTE_SUM=$(git ls-remote --tags --heads 2>/dev/null | git hash-object --stdin) 
if git cat-file -e $REMOTE_SUM 
then 
    echo Remote check-summed up-to-date. 
else 
    echo Remote changed, fetching... 
    git ls-remote --tags --heads 2>/dev/null | \ 
     git hash-object -w --stdin &>/dev/null 
    git fetch 
fi 

一些必要的錯誤檢查被省略,並且代碼被複製爲清楚起見。

說明

清單與git ls-remote --tags --heads所有遠程提示產生輸出如:

 
From /home/user/tmp/repo2 
777201715768a4d82f374f7224e68164a916ac1f  refs/heads/bar 
78981922613b2afb6025042ff6bd878ac1994e85  refs/heads/master 
... 

反過來我們通過git hash-object --stdin和散列遠程回購作爲單個散列的上述圖像檢查我們以前是否通過在git中查詢與git cat-file -e的哈希來查看它。如果我們沒有看到它,遠程圖片必須已經改變,我們首先在git中用git hash-object -w進行記錄,以適應在拉出和提交遙控器之間的比賽,然後繼續獲取遙控器。

可以將它與git預取功能集成:pre-fetch hook functionality in git,但這不在此答案的範圍內。

補遺

注意上面將產生在GIT中鬆散物偶爾將需要被垃圾收集與git gc,以及可能--prune明確。

此外,只要提交沒有按照分支提示保持不變的方式故意重新排列,上述操作就會起作用。這會很/不常見/並且違背git改變推送狀態的指導原則,但是,最糟糕的情況是你跳過了抓取。

另請注意,ls-remote適用於單個遙控器。要使用多個遙控器,您必須通過生成與git remote show遙控器列表來擴展腳本,並依次處理每個遙控器。

+0

聽起來不錯!如果我做了一個強制推送到遠程,它是否工作?當然不會變身。 – fifth

+0

是的分支名稱只是一個提示的名字,即對象樹中的頂級提交。您可以看到ls-remote列出了這些提示,並且當您強制推送提示時會發生變化,遠程快照將會看起來不同,並散列爲不同的散列值,因此將在第一次調用時運行完整提取,隨後沒有。 – mockinterface

2

您沒有訪問origin服務器

你不僅可以使用git

編輯

按照另一個答案,git ls-remote可能對你有用的。

但是,正如你將不得不ls-remote所有的存儲庫,如果你的問題是網絡延遲,它將不會用ls-remote來解決。


您可以訪問origin服務器

  1. 安裝鉤子時,有在服務器上的回購寫。掛鉤會將回購標記爲正在修改。例如,您可以在服務器上的某個位置創建一個repo_name__MODIFIED文件)。
  2. 在更新回購之前,檢查回購是否被修改。對於給定示例,檢查服務器上是否存在文件repo_name__MODIFIED
  3. 如果repo被修改,在更新repo之前,將其標記爲未修改(就在獲取之前)。在我們的示例中,只需刪除服務器上的repo_name__MODIFIED文件即可。

爲什麼取這麼長? git只會取得新的提交,如果沒有修改origin,它應該非常快!

+0

實際上,我的構建機器將獲取數十個回購以獲取最新代碼,單個提取很快,但提取(網絡請求)的總時間持續了幾分鐘。這是糟糕的,或設計不好的機器 – fifth

+0

好吧。那麼你對我的解決方案有什麼看法?你有權訪問原始服務器嗎?如果你需要更多的信息,我可以進一步發展。 – Frizlab

+0

我可以訪問原始服務器,我明白你的解決方案,值得一試,謝謝。 – fifth

0

如果您已經使用git clonegit remote add $REMOTE_NAME $REMOTE_URL,所有你需要在你本地分行到其遠程同行(你的最後一個git fetch的時間)的信息設置了本地存儲庫已經存在。

如果您設置了遠程跟蹤分支,git status會告訴您是否與您正在跟蹤的遠程分支存在差異,如下所示。

$ git status 
On branch master 
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. 
    (use "git pull" to update your local branch) 

Changes not staged for commit: 
    (use "git add <file>..." to update what will be committed) 
    (use "git checkout -- <file>..." to discard changes in working directory) 

     modified: perl/Makefile.am 

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

還有一個解析的形式:

$ git status --porcelain -b 
## master...origin/master [behind 1] 
M perl/Makefile.am 
+0

這不適用於其他地方某人推送的新標籤。 git-status只適用於當前工作樹,我想。 – fifth