Чи є спосіб дізнатись, з якої гілки береться команда, враховуючи хеш-значення SHA-1 ?
Бонусні бали, якщо ви можете сказати мені, як це досягти, використовуючи Ruby Grit.
Чи є спосіб дізнатись, з якої гілки береться команда, враховуючи хеш-значення SHA-1 ?
Бонусні бали, якщо ви можете сказати мені, як це досягти, використовуючи Ruby Grit.
Відповіді:
Хоча Дав вірно вважає, що інформація не зберігається безпосередньо, це не означає, що ви ніколи не можете їх дізнатися. Ось кілька речей, які ви можете зробити.
git branch -a --contains <commit>
Це розповість вам про всі гілки, які в своїй історії дали ці зобов'язання. Очевидно, це менш корисно, якщо коміти вже об'єднані.
Якщо ви працюєте в сховищі, в якому було здійснено фіксацію, ви можете шукати рефлоги в рядку для цього коміту. Reflogs старше 90 днів обрізається git-gc, тому якщо комітка занадто стара, ви її не знайдете. Однак це можна зробити:
git reflog show --all | grep a871742
знайти фіксацію a871742. Зауважте, що ОБОВ'ЯЗКОВО слід використовувати скорочені 7 перших цифр комітів. Вихід повинен бути приблизно таким:
a871742 refs/heads/completion@{0}: commit (amend): mpc-completion: total rewrite
що вказує на те, що зобов’язання було здійснено на філії "завершення". Вихід за замовчуванням показує скорочені хеші фіксації, тож не шукайте повний хеш, інакше ви нічого не знайдете.
git reflog show
насправді є лише псевдонімом git log -g --abbrev-commit --pretty=oneline
, тому, якщо ви хочете поспілкуватися з вихідним форматом, щоб зробити різні речі доступними для грепування, це ваш вихідний пункт!
Якщо ви не працюєте в сховищі, де було здійснено фіксацію, найкраще, що ви можете зробити в цьому випадку - вивчити відкладені файли та виявити, коли комісія вперше була введена у ваше сховище; з будь-якою удачею ви здобули гілку, на яку вона була віддана. Це трохи складніше, тому що ви не можете одночасно ходити і по дереву фіксів, і по відкладенню. Ви хочете проаналізувати вихід рефлогу, вивчаючи кожен хеш, щоб побачити, чи містить він потрібну фіксацію чи ні.
Це залежить від робочого процесу, але при хороших робочих процесах здійснюються комісії в галузях розвитку, які потім об'єднуються. Ви можете зробити це:
git log --merges <commit>..
побачити об'єднання комітетів, які дають фіксацію як предка. (Якщо фіксація була об'єднана лише один раз, першою повинна бути злиття, яку ви шукаєте; в іншому випадку, вам, мабуть, доведеться вивчити декілька.
Якщо ви хочете мати можливість розраховувати на це, ви можете скористатися --no-ff
опцією, git merge
щоб змусити створення об'єднань фіксації навіть у випадку швидкого переходу. (Не надто прагніть, однак, це може стати запаморочливим при надмірному використанні.) Відповідь VonC на відповідне запитання корисно висвітлює цю тему.
git describe
достатньо, тому що (анотовані) теги можуть розглядатися як більш значущі, ніж гілки.
--no-ff
параметр, щоб переконатися, що завжди існує об'єднання об'єднань, так що ви завжди можете простежити шлях даного комітету під час його злиття до головного.
-a
прапор до першої команди, наприкладgit branch -a --contains <commit>
-r
.
merge --no-ff
для надійного запису назви гілки при злитті. Але в іншому випадку розгляньте назви філій як тимчасові короткі мітки, а описи виконайте як постійні. "Яке коротке ім'я ми посилалися на це під час розробки?" насправді не повинно бути настільки важливим питанням, як "що робить це зобов'язання?"
Ця проста команда працює як шарм:
git name-rev <SHA>
Наприклад (де тест-гілка - це назва гілки):
git name-rev 651ad3a
251ad3a remotes/origin/test-branch
Навіть це працює для складних сценаріїв, таких як:
origin/branchA/
/branchB
/commit<SHA1>
/commit<SHA2>
Тут git name-rev commit<SHA2>
повертається відділенняB .
git name-rev --name-only <SHA>
було корисніше отримати лише ім'я гілки. Моє запитання ... Чи може за будь-яких обставин повернути більше однієї гілки?
Оновлення грудня 2013 року:
git-what-branch
(Сценарій Perl, див. Нижче), схоже, більше не підтримується.git-when-merged
це альтернатива, написана на Python, яка працює для мене дуже добре.
Він заснований на " Знайти комісію злиття, яка включає конкретну комісію ".
git when-merged [OPTIONS] COMMIT [BRANCH...]
Знайдіть, коли комісія була об'єднана в одну або кілька гілок.
Знайдіть комісію злиття, внесенуCOMMIT
до вказаних BRANCH (ив).Зокрема, шукайте найдавніший вчинок з історії первинних батьків,
BRANCH
який міститьCOMMIT
як предка.
Оригінальна відповідь вересень 2010 року:
Себастьян Душ щойно твірнув (за 16 хвилин до цієї відповіді ТАК):
git-what-branch : Дізнайтеся, на якій гілці відбувається комісія чи як вона потрапила до названої гілки
Це сценарій Perl від Сет Робертсон, який здається дуже цікавим:
СИНОПИС
git-what-branch [--allref] [--all] [--topo-order | --date-order ]
[--quiet] [--reference-branch=branchname] [--reference=reference]
<commit-hash/tag>...
ОГЛЯД
Розкажіть нам (за замовчуванням) про найдавніший причинний шлях комітетів та злиття для того, щоб запит на комісію потрапив на названу гілку. Якщо комісія була зроблена безпосередньо на названій гілці, це, очевидно, є найбільш раннім шляхом.
Під раннім причинним шляхом ми маємо на увазі шлях, який злився в названу гілку якнайшвидше, за час введення (якщо
--topo-order
не вказано).ДІЯЛЬНІСТЬ
Якщо багато гілок (наприклад, сотні) містять фіксацію, то система може зайняти тривалий час (для певної фіксації в дереві Linux, для дослідження гілки знадобилося 8 секунд, але для визначення маршруту було понад 200 кандидатських гілок) до кожного вчинення.
Вибір конкретної--reference-branch --reference tag
для вивчення буде в сотні разів швидший (якщо у вас є сотні відділень кандидата).ПРИКЛАДИ
# git-what-branch --all 1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4
1f9c381fa3e0b9b9042e310c69df87eaf9b46ea4 first merged onto master using the following minimal temporal path:
v2.6.12-rc3-450-g1f9c381 merged up at v2.6.12-rc3-590-gbfd4bda (Thu May 5 08:59:37 2005)
v2.6.12-rc3-590-gbfd4bda merged up at v2.6.12-rc3-461-g84e48b6 (Tue May 3 18:27:24 2005)
v2.6.12-rc3-461-g84e48b6 is on master
v2.6.12-rc3-461-g84e48b6 is on v2.6.12-n
[...]
Ця програма не враховує наслідків вибору вишні, що цікавить, лише операції з об'єднання.
git-what-branch
схоже, не підтримується більше. git-kada-spared - це альтернатива, написана на Python, яка працює для мене дуже добре.
Наприклад, щоб визначити, що цей c0118fa
комітет прийшов від redesign_interactions
:
* ccfd449 (HEAD -> develop) Require to return undef if no digits found
* 93dd5ff Merge pull request #4 from KES777/clean_api
|\
| * 39d82d1 Fix tc0118faests for debugging debugger internals
| * ed67179 Move &push_frame out of core
| * 2fd84b5 Do not lose info about call point
| * 3ab09a2 Improve debugger output: Show info about emitted events
| * a435005 Merge branch 'redesign_interactions' into clean_api
| |\
| | * a06cc29 Code comments
| | * d5d6266 Remove copy/paste code
| | * c0118fa Allow command to choose how continue interaction
| | * 19cb534 Emit &interact event
Вам слід запустити:
git log c0118fa..HEAD --ancestry-path --merges
І прокрутіть униз, щоб знайти останню комісію злиття . Який:
commit a435005445a6752dfe788b8d994e155b3cd9778f
Merge: 0953cac a06cc29
Author: Eugen Konkov
Date: Sat Oct 1 00:54:18 2016 +0300
Merge branch 'redesign_interactions' into clean_api
Оновлення
Або лише одна команда:
git log c0118fa..HEAD --ancestry-path --merges --oneline --color | tail -n 1
git merge -m"Any String Here"
буде затьмарювати вихідну та цільову інформацію про галузь.
Merge: f6b70fa d58bdcb
. Ви можете назвати свою комісію злиття, як і ви. Я не матиму справи
git branch --contains <ref>
є найбільш очевидною "порцеляновою" командою для цього. Якщо ви хочете зробити щось подібне лише за допомогою "сантехнічних" команд:
COMMIT=$(git rev-parse <ref>) # expands hash if needed
for BRANCH in $(git for-each-ref --format "%(refname)" refs/heads); do
if $(git rev-list $BRANCH | fgrep -q $COMMIT); then
echo $BRANCH
fi
done
(перехресний відповідь з цієї відповіді ТАК )
khichar.anil висвітлював більшість цього у своїй відповіді.
Я просто додаю прапор, який видалить теги зі списку імен редакції. Це дає нам:
git name-rev --name-only --exclude=tags/* $SHA
Варіант бідної людини - використовувати інструмент tig
1 увімкнено HEAD
, здійснити пошук фіксації, а потім візуально дотримуватися рядка з цього комікату, поки не буде показано об'єднання об'єднань. Повідомлення злиття за замовчуванням повинно вказувати, до якої гілки об'єднується куди :)
1 Tig - це інтерфейс текстового режиму для Git на основі ncurses. Він функціонує, головним чином, як браузер репозиторію Git, але також може допомогти в постановці змін для фіксації на рівні фрагментів і виступати в якості пейджера для виводу з різних команд Git.
В якості експерименту я зробив гачок після фіксації, який зберігає інформацію про поточно перевірену гілку у метаданих фіксації. Я також трохи змінив gitk, щоб показати цю інформацію.
Перевірити це можна тут: https://github.com/pajp/branch-info-commissions
Я маю справу з тією самою проблемою ( багатогалузевий трубопровід Дженкінса ) - маючи лише введення інформації та намагаючись знайти ім'я філії, звідки походить цей комітет. Він повинен працювати для віддалених відділень, локальні копії недоступні.
Це те, з чим я працюю:
git rev-parse HEAD | xargs git name-rev
За бажанням можна зняти вихід:
git rev-parse HEAD | xargs git name-rev | cut -d' ' -f2 | sed 's/remotes\/origin\///g'
Я думаю, що хтось повинен зіткнутися з тією ж проблемою, яка не може дізнатися галузь, хоча вона насправді існує в одній галузі.
Ви краще перетягніть все спочатку:
git pull --all
Потім виконайте пошук філії:
git name-rev <SHA>
або:
git branch --contains <SHA>
Якщо ОП намагається визначити історію, яку проходила гілка, коли було створено певний комітет ("з'ясуйте, з якої гілки комісія походить з огляду на її хеш-значення SHA-1"), то без рефлогу не буде жодної записи в базі даних об’єктів Git, які показують, яка названа гілка була пов'язана з історією фіксації.
(Я опублікував це як відповідь у відповідь на коментар.)
Сподіваюся, цей сценарій ілюструє мою точку зору:
rm -rf /tmp/r1 /tmp/r2; mkdir /tmp/r1; cd /tmp/r1
git init; git config user.name n; git config user.email e@x.io
git commit -m"empty" --allow-empty; git branch -m b1; git branch b2
git checkout b1; touch f1; git add f1; git commit -m"Add f1"
git checkout b2; touch f2; git add f2; git commit -m"Add f2"
git merge -m"merge branches" b1; git checkout b1; git merge b2
git clone /tmp/r1 /tmp/r2; cd /tmp/r2; git fetch origin b2:b2
set -x;
cd /tmp/r1; git log --oneline --graph --decorate; git reflog b1; git reflog b2;
cd /tmp/r2; git log --oneline --graph --decorate; git reflog b1; git reflog b2;
Вихід показує відсутність будь-якого способу дізнатися, чи приходить команда "Add f1" з гілки b1 або b2 з віддаленого клону / tmp / r2.
(Останні рядки виводу тут)
+ cd /tmp/r1
+ git log --oneline --graph --decorate
* f0c707d (HEAD, b2, b1) merge branches
|\
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: merge b2: Fast-forward
086c9ce b1@{1}: commit: Add f1
18feb84 b1@{2}: Branch: renamed refs/heads/master to refs/heads/b1
18feb84 b1@{3}: commit (initial): empty
+ git reflog b2
f0c707d b2@{0}: merge b1: Merge made by the 'recursive' strategy.
80c10e5 b2@{1}: commit: Add f2
18feb84 b2@{2}: branch: Created from b1
+ cd /tmp/r2
+ git log --oneline --graph --decorate
* f0c707d (HEAD, origin/b2, origin/b1, origin/HEAD, b2, b1) merge branches
|\
| * 086c9ce Add f1
* | 80c10e5 Add f2
|/
* 18feb84 empty
+ git reflog b1
f0c707d b1@{0}: clone: from /tmp/r1
+ git reflog b2
f0c707d b2@{0}: fetch origin b2:b2: storing head
git log 80c10e5..HEAD --ancestry-path --merges --oneline --color | tail -n 1
і git log 086c9ce..HEAD --ancestry-path --merges --oneline --color | tail -n 1
команди для обох випадків?
$ git log HEAD^1..HEAD --ancestry-path --merges --oneline --color | tail -n 1
які виходи 376142d merge branches
та $ git log HEAD^2..HEAD --ancestry-path --merges --oneline --color | tail -n 1
які виходи 376142d merge branches
- які показують підсумок злуки злиття, який (як я стверджував) може бути перезаписаний під час створення об’єднання, можливо, обтяжуючи історію гілки злиття.
Скористайтеся наведеним нижче, якщо вам важливо статуси виходу з оболонки:
branch-current
- назва поточної філіїbranch-names
- чисті назви гілок (по одному на рядок)branch-name
- Переконайтеся, що повернуто лише одну гілку branch-names
Обидва branch-name
і branch-names
приймають команду як аргумент, а за замовчуванням - HEAD
якщо не вказано жодне.
branch-current = "symbolic-ref --short HEAD" # https://stackoverflow.com/a/19585361/5353461
branch-names = !"[ -z \"$1\" ] && git branch-current 2>/dev/null || git branch --format='%(refname:short)' --contains \"${1:-HEAD}\" #" # https://stackoverflow.com/a/19585361/5353461
branch-name = !"br=$(git branch-names \"$1\") && case \"$br\" in *$'\\n'*) printf \"Multiple branches:\\n%s\" \"$br\">&2; exit 1;; esac; echo \"$br\" #"
% git branch-name eae13ea
master
% echo $?
0
0
.% git branch-name 4bc6188
Multiple branches:
attempt-extract
master%
% echo $?
1
1
.Через стан виходу їх можна безпечно надбудовувати. Наприклад, щоб отримати пульт дистанційного використання для отримання:
remote-fetch = !"branch=$(git branch-name \"$1\") && git config branch.\"$branch\".remote || echo origin #"
Щоб знайти місцеве відділення:
grep -lR YOUR_COMMIT .git/refs/heads | sed 's/.git\/refs\/heads\///g'
Щоб знайти віддалену гілку:
grep -lR $commit .git/refs/remotes | sed 's/.git\/refs\/remotes\///g'