2010-02-18 76 views
4

這是怎麼gitk目前看起來我們的項目之一:奇怪git的合併問題

https://dl.dropbox.com/u/2582508/gitk.png

這顯然是,所有我們可以知道,發生了一個「混帳合併」用遙控器完成後,分支 - 我們不知道爲什麼或者發生了什麼。有什麼想法發生在這裏?

更重要的是,最好的解決方法是什麼?那些合併提交是空的,但是當做「git rebase -i」合併提交通常似乎不會出現。

最重要的是,我寧願不要讓歷史與其他克隆不兼容,即它們仍應該能夠拉/推/合併它。這甚至有可能嗎?

+0

我只是放棄這個克隆,克隆另一個副本。這個克隆中是否有任何「未備份的分支/提交」? – 2010-02-18 14:48:42

+0

您是否通過中央存儲庫共享(即,您是否都在共同存儲庫中進行推送和共享)? – 2010-02-18 19:15:27

+0

是的,有一個公共存儲庫,並且已經完成了進一步的工作。 – miracle2k 2010-02-20 06:35:57

回答

3

這是某人使用git pull(或等同於git fetchgit merge)更新項目的結果。想象一下,你是庫看起來像是這樣的:

 
o---o---o [origin/master] 
     \ 
      A---B---C [master] 

也就是說,你所做的承諾A,在什麼是原回購頂部BC

與此同時,其他人進行更改並將其推送到共享存儲庫。如果你再運行git fetch你的資料庫是這樣的:

 
o---o---o---D---E---F [origin/master] 
     \ 
      A---B---C [master] 

現在,如果你運行git merge(記住:git pull只是git fetch其次是git merge)。你也會有這樣的:

 
o---o---o---D---E---F [origin/master] 
     \   \ 
      A---B---C---G [master] 

假設一切順利,G可能只是一個「愚蠢」的合併提交;從技術上講,G的狀態不同於FC,所以它必須有不同的考慮。現在

,如果你把這個變化,你就會有這樣的:

 
o---o---o---D---E---F 
     \   \ 
      A---B---C---G [origin/master] 

如果你繼續發展你會得到這樣的:

 
o---o---o---D---E---F 
     \   \ 
      A---B---C---G [origin/master] 
         \ 
         H---I---J [master] 

現在,如果你繼續這樣做(如果許多人繼續這樣做),你最終會得到一張像你圖片中的那棵樹。這不是「錯誤」,但許多人不喜歡它,因爲它使得發展史難以跟上。

解決這個問題的方法是教人們重新定位。 Rebasing會(如你所記錄的)遠離無用的合併提交,並且給你一個更清晰的歷史記錄。在上面的例子中,你會得到一個線性的發展歷史。這更容易遵循。但是,您需要知道,在重新綁定之後,您需要重新編譯和重新測試代碼......僅僅因爲合併代碼並不意味着結果是正確的。

如果您使用中央存儲庫共享官方開發線,則可以實施預接收掛鉤,以檢測這些自動(「愚蠢」/「無用」)合併提交併拒絕推送 - 強制用戶要麼變硬。實際上,您希望掛鉤查找默認的合併提交消息...所以,如果你確實想保持合併提交(有時候這很有意義),你至少必須編寫一個智能提交消息。

下面是一個示例鉤子。我剝去了一堆額外的東西,所以我沒有去測試它。

 
#!/bin/bash 

# This script is based on Gnome's pre-receive-check-policy hook. 
# This script *only* checks for extraneous merge commits. 

# Used in some of the messages 
server=git.wherever.com 

GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) 

in_import() { 
    test -e "$GIT_DIR/pending" 
} 

forced() { 
    test -n "$GNOME_GIT_FORCE" 
} 

check_commit() { 
    commit=$1 

    subject="$(git log $commit -1 --pretty=format:%s)" 
    if expr "$subject" : ".*Merge branch.*of.*\(git\|ssh\):" > /dev/null 2>&1; then 
      if ! in_import && ! forced ; then 
       cat &2 
--- 
The commit: 

EOF 
     git log $commit -1 >&2 
     cat &2 

Looks like it was produced by typing 'git pull' without the --rebase 
option when you had local changes. Running 'git pull --rebase' now 
will fix the problem. Then please try, 'git push' again. Please see: 

    http://live.gnome.org/Git/Help/ExtraMergeCommits 
--- 
EOF 
     exit 1 
      fi 
    fi 
} 

check_ref_update() { 
    oldrev=$1 
    newrev=$2 
    refname=$3 

    change_type=update 
    if expr $oldrev : "^0\+$" > /dev/null 2>&1; then 
    change_type=create 
    fi 

    if expr $newrev : "^0\+$" > /dev/null 2>&1; then 
      if [ x$change_type = xcreate ] ; then 
      # Deleting an invalid ref, allow 
       return 0 
      fi 
      change_type=delete 
    fi 

    case $refname in 
    refs/heads/*) 
     # Branch update 
     branchname=${refname#refs/heads/} 

     range= 
     # For new commits introduced with this branch update, we want to 
     # run some checks to catch common mistakes. 
     # 
     # Expression here is same as in post-receive-notify-cia; we take 
     # all the branches in the repo, as "^/ref/heads/branchname", other 
     # than the branch we are actualy committing to, and exclude commits 
     # already on those branches from the list of commits between 
     # $oldrev and $newrev. 

     if [ -n "$range" ] ; then 
     for merged in $(git rev-parse --symbolic-full-name --not --branches | \ 
        egrep -v "^\^$refname$" | \ 
      git rev-list --reverse --stdin "$range"); do 
      check_commit $merged 
     done 
     fi 
     ;; 
    esac 

    return 0 
} 

if [ $# = 3 ] ; then 
    check_ref_update [email protected] 
else 
    while read oldrev newrev refname; do 
    check_ref_update $oldrev $newrev $refname 
    done 
fi 

exit 0 
+0

感謝您的回答。但是,我要麼不理解它,要麼我不清楚我的問題。我理解合併提交,我很高興讓他們進入中央回購 - 我不認爲我們想在這裏使用rebase。但在上面的屏幕截圖中,我已經使用了。像30次後續合併,每次合併都有兩位父母:直接合並,以及一系列較老的提交。沒有30個開發合併開發步驟。雖然我很難理解這些樹木,但對我來說合並似乎也是沒有必要的。一個人(或幾個人)可以完成你描述的目標。 – miracle2k 2010-02-20 06:34:10