Uzak deponun geliştirme dalının bir kopyasına sahip olduğu varsayılarak (ilk açıklamanız yerel bir depoda açıklanır, ancak uzaktan kumandada da varmış gibi görünür), istediğinizi, ancak yaklaşımı elde edebilmeniz gerekir. öngördüğünüzden biraz farklı.
Git'in geçmişi bir DAG taahhütüne dayanmaktadır . Şubeler (ve genel olarak "referanslar"), sürekli büyüyen taahhüt DAG'sindeki belirli taahhütlere işaret eden geçici etiketlerdir. Bu nedenle, dallar arasındaki ilişki zaman içinde değişebilir, ancak taahhütler arasındaki ilişki değişmez.
---o---1 foo
\
2---3---o bar
\
4
\
5---6 baz
Görünüşe bazgöre (eski bir sürümü) bar? Peki ya silersek bar?
---o---1 foo
\
2---3
\
4
\
5---6 baz
Şimdi bazdayanıyor gibi görünüyor foo. Ancak, soyları bazdeğişmedi, sadece bir etiketi (ve ortaya çıkan sarkan taahhüdü) kaldırdık. Ya yeni bir etiket eklersek 4?
---o---1 foo
\
2---3
\
4 quux
\
5---6 baz
Şimdi bazdayanıyor gibi görünüyor quux. Yine de, soy değişmedi, sadece etiketler değişti.
Ancak, “taahhüt 6bir taahhüt torunu 3mu?” Diye sorsaydık. (varsayarak 3ve 6ister, o zaman cevabı “evet” olacağını SHA-1 adları işlemek dolu) barve quuxetiketlerin mevcut veya değildir.
Böylece, “itilen taahhüt geliştirme dalının mevcut ucunun bir inişi mi?” Gibi sorular sorabilirsiniz , ancak “itilen taahhüdün ana kolu nedir?” Diye soramazsınız.
İstediğiniz şeye yaklaşan çoğunlukla güvenilir bir soru:
Ebeveyn olarak mevcut geliştirme ipucuna sahip olan tüm itilmiş taahhüdün ataları (mevcut geliştirme ucu ve ataları hariç) için :
- böyle bir taahhüt var mı?
- tüm bu taahhütler tek ebeveynli taahhütler midir?
Hangi olarak uygulanabilir:
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
echo "'$basename' is missing, call for help!"
exit 1
fi
parents_of_children_of_base="$(
git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
grep -F "$baserev"
)"
case ",$parents_of_children_of_base" in
,) echo "must descend from tip of '$basename'"
exit 1 ;;
,*\ *) echo "must not merge tip of '$basename' (rebase instead)"
exit 1 ;;
,*) exit 0 ;;
esac
Bu, kısıtlamak istediğiniz şeylerin bazılarını kapsayacaktır, ancak belki her şey olmayabilir.
Başvuru için, genişletilmiş bir örnek geçmişi aşağıda verilmiştir:
A master
\
\ o-----J
\ / \
\ | o---K---L
\ |/
C--------------D develop
\ |\
F---G---H | F'--G'--H'
| |\
| | o---o---o---N
\ \ \ \
\ \ o---o---P
\ \
R---S
Yukarıdaki kod reddetmek için kullanılabilir Hve Skabul ederken H', J, K, veya N, ama aynı zamanda kabul edeceğini Lve P(onlar birleştirmeleri dahil, ancak ucu birleştirmezseniz geliştirmek ).
Ayrıca reddetmek Lve Psoruyu değiştirmek ve
Tüm itilen taahhütlerin ataları için (mevcut geliştirme ipucu ve ataları hariç ):
- iki ebeveyn ile herhangi bir taahhüt var mı?
- değilse, böyle bir taahhüt en azından bir ebeveynini geliştirmek için mevcut ipucuna sahip mi?
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
echo "'$basename' is missing, call for help!"
exit 1
fi
parents_of_commits_beyond_base="$(
git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
grep -v '^commit '
)"
case "$parents_of_commits_beyond_base" in
*\ *) echo "must not push merge commits (rebase instead)"
exit 1 ;;
*"$baserev"*) exit 0 ;;
*) echo "must descend from tip of '$basename'"
exit 1 ;;
esac