我有兩個分支:主幹,生產。我在後備箱裏發現了一個問題,做了修理並將其付諸實施,並將其推出。現在已經過測試,我需要將更改合併到生產分支中作爲熱修復。我嘗試使用櫻桃挑選。但是它不起作用,因爲在我不想投入生產的一些重構過程中,修正中的更改文件在主幹中被重命名。從重命名文件的backport更改
我不想合併的一切,但只拿這個承諾。櫻桃挑選失敗並且「被我們刪除」衝突(當然,新文件甚至從未在生產分支中存在)。
什麼是把變成舊的文件正確的方法是什麼?
我有兩個分支:主幹,生產。我在後備箱裏發現了一個問題,做了修理並將其付諸實施,並將其推出。現在已經過測試,我需要將更改合併到生產分支中作爲熱修復。我嘗試使用櫻桃挑選。但是它不起作用,因爲在我不想投入生產的一些重構過程中,修正中的更改文件在主幹中被重命名。從重命名文件的backport更改
我不想合併的一切,但只拿這個承諾。櫻桃挑選失敗並且「被我們刪除」衝突(當然,新文件甚至從未在生產分支中存在)。
什麼是把變成舊的文件正確的方法是什麼?
我會用好老補丁這樣的:
git show COMMIT_ID -- old/file/name.txt | patch new/file/name.txt
這有點棘手。例如,您可以從差異創建補丁並將其應用於舊文件。但是爲了避免這些問題,我建議在生產分支上進行修復,然後在那裏進行測試,然後從生產合併到主幹。
是的,我知道,但是並不總是可以預測進入hot-fix的內容。我試圖通過'format-patch' /'apply-patch'來完成,但它什麼也沒做(沒有錯誤,也沒有改變)。請給出適當的使用方法。 – kan 2012-03-19 15:42:38
查看本帖子中的「重命名git處理」一節http://blogs.atlassian.com/2011/10/confluence_git_rename_merge_oh_my/ – ralphtheninja 2012-03-19 16:03:44
我遇到同樣的問題,並試圖找到一個解決方案。
我解決了用底墊的序列。 我沒有做過進一步的測試,所以請自行承擔風險!
如果your're興趣看看它在GitHub上:
櫻桃採摘修改任意數量的文件,目錄中的情況下,部門之間的重新命名:
git diff ... | sed -e 's|<old dir>|<new dir>|' | git apply -
如果:
...那麼你絕對應該考慮改變你的混帳配置是這樣的:
$ git config merge.renameLimit 999999
這是可能的合併/摘櫻桃時,Git是擊中默認文件檢查限制(我認爲這是400或1000或類似的東西)之前,它是能夠找到合適的命名比賽。提高此限制可能會導致合併/櫻桃選擇花費更長時間來搜索您的重命名文件,但它可以幫助避免「被我們刪除」合併挑戰。
這應該做的伎倆,但如果你重命名的文件很小,分支機構之間的變化是顯著,你也可以用-X rename-threshold
設置,例如玩使用-X rename-threshold=25%
將其從默認的50%降低。
關於其他用戶的'rename-threshold'的說明 - 這包括所有隨時間的變化。我有一個合併的地方,原來的重命名改變了文件中的兩行,但是由於它已經在*那個點之後進行了大量修改,所以git在沒有降低'rename-threshold'的情況下仍然沒有檢測到文件相似性。 – zebediah49 2016-06-02 18:36:56
同樣的問題面前,我問一個同事他會做什麼,他的即時反應是:
git checkout production
git mv production-filename trunk-filename && git commit -m "Just fooling git"
git cherry-pick trunk-commit
git mv trunk-filename production-filename && git commit -m "Undo the damage"
# Now squash the 3 commits
git rebase -i HEAD~3
工作就像對我的魅力。
這工作從我。我使用了GUI,但是遵循了相同的步驟。 我花了一分鐘的時間來弄清楚這是做什麼,所以我會列出步驟: 1.重命名目標分支上的文件/目錄以匹配源分支並提交。 2. Cherrypick從源分支到目標分支的更改。 3.將目標分支上的文件/目錄重命名爲它們原來的狀態並提交。 4.將這3個提交壓縮爲一個提交。 – Tolli 2017-08-29 20:05:59
我做了一個shell腳本,在猜測文件移動的時候嘗試做一個櫻桃選擇(如果你重命名文件本身,只有當你將它移動到另一個文件夾,它纔會工作): 但是:目前它會如果提交添加新文件或其自身重命名文件,則失敗。
#!/bin/bash
#
# Attemps to guess file moves (rename of folders) when cherry-pick'ing.
# Gaspard van Koningsveld
#
[ "$1" == "" ] && echo "usage: $0 <commit-hash-to-cherry-pick>" && exit 1
TMP_PATCH_FILE="temp-cherry-pick-patch"
function abort() {
echo "Aborting"
"rm" -f "$TMP_PATCH_FILE"
exit 1
}
function main() {
echo "Retreiving commit patch..."
"git" show "$1" > "$TMP_PATCH_FILE" || abort
echo "Matching renamed files..."
sedcmds=""
for oldfile in $("grep" -E '(--- a|\+\+\+ b)' "$TMP_PATCH_FILE" | "cut" -c 7- | "sort" | "uniq"); do
[ -f "$oldfile" ] && continue
renamefound=0
oldfilepart="$oldfile"
while [ $renamefound -eq 0 ]; do
possiblefiles=$("git" ls-files "**/$oldfilepart")
if [ "$possiblefiles" != "" ]; then
if [ $("wc" -l <<< "$possiblefiles") == "1" ]; then
echo " $oldfile > $possiblefiles"
sedcmds="$sedcmds s|/$oldfile|/$possiblefiles|g;"
break
else
echo " ERROR: More than one rename possibility found for file $oldfile:"
echo "$possiblefiles"
abort
fi
fi
prevoldfilepart="$oldfilepart"
oldfilepart="${oldfilepart#*/}"
if [ "$prevoldfilepart" == "$oldfilepart" ]; then
echo " ERROR: Could not find rename for $oldfile."
abort
fi
done
done
echo "Renaming files in patch..."
"sed" -i "$sedcmds" "$TMP_PATCH_FILE" || abort
echo "Applying patch as new commit..."
"sed" -i "s/^commit /From commit /;s/^Author: /From: /" "$TMP_PATCH_FILE" || abort
"git" am -3 "$TMP_PATCH_FILE"
"rm" -f "$TMP_PATCH_FILE"
}
main "[email protected]"
是的,它適用於我。然而,找到更好的解決方案會很有趣,特別是在有多個重命名文件的情況下。 – kan 2012-03-19 18:41:22