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 baz
göre (eski bir sürümü) bar
? Peki ya silersek bar
?
---o---1 foo
\
2---3
\
4
\
5---6 baz
Şimdi baz
dayanıyor gibi görünüyor foo
. Ancak, soyları baz
değ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 baz
dayanıyor gibi görünüyor quux
. Yine de, soy değişmedi, sadece etiketler değişti.
Ancak, “taahhüt 6
bir taahhüt torunu 3
mu?” Diye sorsaydık. (varsayarak 3
ve 6
ister, o zaman cevabı “evet” olacağını SHA-1 adları işlemek dolu) bar
ve quux
etiketlerin 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 H
ve S
kabul ederken H'
, J
, K
, veya N
, ama aynı zamanda kabul edeceğini L
ve P
(onlar birleştirmeleri dahil, ancak ucu birleştirmezseniz geliştirmek ).
Ayrıca reddetmek L
ve P
soruyu 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