簡體   English   中英

如何知道本地倉庫與遠程倉庫不同,沒有提取?

[英]How to know local repo is different from remote repo, without fetch?

我有幾十個repos,如果發生任何差異,我的腳本應該更新它們,新提交,新標記,新分支。 在我的情況下,Fetch對於幾十個回購來說有點慢,我想知道是否有任何快速命令可以滿足我的要求。

您可以使用git ls-remote plumbing命令獲取沒有fetch的遙控器狀態。

在這里,讓我們使用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列出所有遠程提示git ls-remote --tags --heads生成輸出,例如:

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

反過來我們通過git hash-object --stdin將遠程倉庫的上面圖片作為單個哈希git hash-object --stdin並檢查我們之前是否通過git cat-file -e查詢git中的哈希來看到它。 如果我們還沒有看到它,遠程圖片必須已經改變,我們首先用git hash-object -w在git中記錄它,以適應拉動和提交遙控器之間的比賽,然后繼續獲取遙控器。

可以將它與git預取功能集成:git中的預取鈎子功能 ,但這超出了這個答案的范圍。

附錄

請注意,上面將在git中生成松散的對象,偶爾需要使用git gc進行垃圾收集,並且可能--prune明確地使用--prune

此外,上述內容應該有效,只要提交不是故意重新排列,使得分支尖端保持不變。 這將是/非常罕見的/並且反對改變推送狀態的git指導,但是,嘿,可能發生的最糟糕的事情是你跳過了一個提取。

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

您無權訪問origin服務器

你不能只使用git

編輯

根據另一個答案, git ls-remote可能對您有用。

但是,由於您需要ls-remote所有存儲庫,如果您的問題是網絡延遲,則無法使用ls-remote解決。


您可以訪問origin服務器

  1. 在服務器上的repo上寫入時設置掛鈎。 鈎子會將repo標記為被修改。 例如,您可以在服務器上的某處創建repo_name__MODIFIED文件。
  2. 在更新倉庫之前,請檢查倉庫是否已修改。 對於給定的示例,請檢查服務器上repo_name__MODIFIED存在repo_name__MODIFIED文件。
  3. 如果修改了repo,則在更新repo之前,將其標記為未修改(在獲取之前)。 在我們的示例中,只需刪除服務器上的repo_name__MODIFIED文件即可。

注意

為什么取這么長? git只會獲取新的提交,如果沒有對origin修改,它應該非常快!

如果您使用git clonegit remote add $REMOTE_NAME $REMOTE_URL設置了本地存儲庫,那么將本地分支與遠程對應git 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM