Вопрос по git – Git и лог порядок

7

Я пытался создать линейный порядок из вывода «git log», но все мои попытки потерпели неудачу. Мне нужно сопоставить коммит со следующим выпуском, который содержит этот коммит. Я не могу бежать

git tag --contains <commit>

для каждого коммита, так как наш репозиторий содержит чрезвычайно большое количество коммитов (более 300 000).

Сначала я попробовал использовать

git log --pretty=format:"%ct%H" | sort --key=1,10 

чтобы получить линейный порядок, основанный на времени фиксации. Однако это не дает 100% точного результата. Это приводит к моему первому вопросу:

Q1) Как git хранит время коммитов, когда коммиты помещаются в основной репозиторий? Сохраняет ли оно текущее машинное время для каждого коммита в UTC?

Я также посмотрел «git help log», и в документации говорится, что по умолчанию git log перечисляет коммиты в хронологическом порядке. В моем проекте я проверил, вносил ли я какую-либо ошибку, но насколько я могу судить, код верен, и хронологический порядок, заданный git log, не является линейным порядком. Наконец, мой вопрос?

Q2) Как можно получить линейный порядок из "git log", учитывая, что git не хранит номера ревизий?

Благодарность :

Вы можете сами добавить этот комментарий в качестве ответа, если хотите, тогда другие смогут его подтвердить. Это также означает, что другие увидят, что на этот вопрос дан ответ. Alexander Bird
Попытки описаны в тексте: попытка 1) git log --pretty = format: "% ct% H" | sort --key = 1,10 попытка 2) просто используя порядок по умолчанию (хронологический порядок), заданный git log leco
На вопрос нет ответа. Я только что опубликовал комментарий, чтобы уточнить, что в тексте действительно были упомянуты попытки, которые я попробовал. Некоторое время назад кто-то утверждал, что это не было упомянуто в моем описании, поэтому я добавил этот комментарий, просто чтобы убедиться :) Кстати, человек, который написал эти комментарии, в конечном итоге удалил свой пост и проголосовал против вопроса: P leco

Ваш Ответ

1   ответ
10
# 1: Как git store фиксирует время коммитов, когда коммиты помещаются в главный репозиторий? Сохраняет ли оно текущее машинное время для каждого коммита в UTC?

man git-commit:

Git внутренний формат
Это [отметка времени unix] [смещение часового пояса], где [отметка времени unix] - это количество секунд с начала эпохи UNIX. [смещение часового пояса] является положительным или отрицательным смещением от UTC.

Исходя из этого, внутренне используемый формат времени git: UNIX время эпохи, включая машины со смещением UTC.

# 2: Как можно получить линейный порядок из «git log», учитывая, что git не хранит номера ревизий?

Метод, который вы использовали git log --pretty=format:"%ct%H") будет извлекать данные из все ветви которые были объединены с текущей веткой.

Это делает «линейный порядок» несколько сложным. Рассмотрим следующее источник: git-scm.org]:

Итак, здесь мы работаем над несколькими «ветками тем». Затем мы решили сохранить некоторые dumbidea а такжеiss91v2), отбрасывая других iss91). Итак, мы отбрасываемC5 а такжеC6, сохраняя остальные коммиты, и наша история после слияния выглядит следующим образом источник: git-scm.org]:

(Стрелки указываюто children К parents; C14 это Ребенка коммитовC13 а такжеC11).

Так что теперь у нас есть одинHEAD commit, который, ради аргумента, мы предположим, что мы собираемся выпустить какRELEASE1 или что-то. Итак, на вопрос: как мы можем теперь, имея эту историю, извлечь Линейная, хронологически правильный список коммитов?

Простой ответ: я не верю, что вы можете - или, если вы это сделаете, я не верю, что это будет то, что вы хотите.

Вымо сортировать коммиты линейно, по времени:

git log --pretty=format:"%ct %H" | sort --key=1,10

Это даст вам список, соответствующий:

C1
C2
... snip ...
C13
C14

метьте, однако, что это на самом деле не линейная история! Это потому, что мы объединили несколько ветвей, которые были созданыв то же врем. Мы не можем извлечь линейную историю родителейC14 (нашHEAD), потому что его нет - это дочерний элемент двух ветвей, а не дочерний элемент одного коммита, и это не линейные отношения.

Итак, вы утверждаете, что я могу получить линейную историю только одной ветви?C14 -> C13 ... C3 -> C1, например

Это тоже как минимум очень сложно и (что более вероятно) невозможно.

Эта проблема усугубляется, когда мы объединяем несколько ветвей (слияние 3 или более).Этот вопро более подробно расскажет о причинах, по которым вы не можете извлечь историю «одной ветви» - когда вы смотрите на родителей коммит-слияния, как вы решаете, что такое «одна ветка», а какая ветвь 'присоединения'?

Говоря все это, если вы посмотрите, например, журналы для этого небольшого хранилища, в графическом формате: (я сделал несколько коммитов, которые были бесполезны)


zsh% git log --graph --all --format=format:'%C(blue)%h%C(reset) - %C(green)(%cr)%C(reset)                %C(yellow)%d%C(reset)' --abbrev-commit --date=relative
* 3cf5f06 - (8 weeks ago)  (origin/master, origin/HEAD, master)
* a3a3205 - (4 months ago) 
* c033bf9 - (4 months ago)  (origin/svg)
* ccee435 - (4 months ago) 
*   f08bc1e - (4 months ago) 
|\  
| * 48c4406 - (5 months ago) 
* | 203eeaa - (4 months ago) 
* | 5fb0ea9 - (5 months ago) 
|/  
* 39bccb8 - (5 months ago)

метьте, что это историяявляетс в хронологическом порядке; хотя ветви не были «сплющены» в одну, поэтому это выглядит немного странно. Каждый из этих коммитов содержится в текущемHEAD (master, origin/master). Это очевидно, потому что обе вилки в истории были объединены (слияние вf08bc1e).

# 3: мне нужно сопоставить коммит со следующей версией, содержащей этот коммит

Если ты заинтересован вindividual commit, этот вопро, или если ваши выпуски помечены помогу

Читая вопрос, кажется, тыможе хочу нанести на карту каждый коммит до релиза; это большая работа, и я не могу помочь с этим - я не думаю, что вам нужно проверять каждый коммит, потому что ветки будут объединены, и если в выпуске будет заголовок линейной ветви, линейные родители тоже будут. Если вы не занимались сбором вишни или чем-то подобным.

Если вы отсортировали по времени, а затем проверили все коммиты, более старые, чем ваш самый старый выпуск, запишите этот идентификатор коммита, если он был включен в самый старый, затем второй самый старый и т. Д., И удалите коммит из списка, когда вы найдете релиз, содержащий это, вам придется проверить не болееnumber of releases * number of commits; в худшем случае, нет коммита в любом выпуске. В лучшем случае, релизы содержат каждый коммит старше, чем он сам, то есть300,000 проверяет. Еще много, но (на мой взгляд) выполнимо.

(Извиняюсь за длинный ответ).

Для глубоких ссылок вы должны использовать ближайший якорь на странице, который в данном случае относится к самому разделу ФОРМАТЫ ДАТЫ: Kernel.org / паб / программное обеспечение / SCM / мерзавец / документы / .... Я использую расширение якоря расширения Firefox для этой цели, чтобы добавить глубокие ссылки на мои письма. Вы можете просмотреть источник и найти якоря, но это может стать утомительным. Miserable Variable

Похожие вопросы