diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
int get_verbosely = 0;
int get_recover = 0;
+ prefix = setup_git_directory();
+
git_config(git_default_config, NULL);
while (arg < argc && argv[arg][0] == '-') {
Давайте проанализируем этот патч построчно.
Первая строка
diff --git a / builtin-http-fetch.cb / http-fetch.c
это заголовок "git diff" в форме diff --git a/file1 b/file2. a/И b/имена файлов являются одинаковыми , если переименовать / копировать не участвует (как в нашем случае). Это --gitозначает, что diff находится в формате «git» diff.
Далее идет одна или несколько расширенных строк заголовка. Первые три
индекс сходства 95%
переименовать из встроенного-http-fetch.c
переименовать в http-fetch.c
скажите нам, что файл был переименован из builtin-http-fetch.cв http-fetch.cи что эти два файла идентичны на 95% (что использовалось для обнаружения этого переименования).
Последняя строка в расширенном заголовке diff, который
индекс f3e63d7..e8f44ba 100644
расскажите нам о режиме данного файла (это 100644означает, что это обычный файл, а не, например, символическая ссылка, и что он не имеет исполняемого бита разрешения), и о сокращенном хеше preimage (версия файла перед данным изменением) и postimage ( версия файла после изменения). Эта строка используется, git am --3wayчтобы попытаться выполнить трехстороннее слияние, если патч не может быть применен сам по себе.
Далее идет двухстрочный унифицированный заголовок diff
--- a / builtin-http-fetch.c
+++ b / http-fetch.c
По сравнению с diff -Uрезультатом он не имеет ни времени изменения файла, ни времени изменения файла после исходного (preimage) и конечного (postimage) имен файлов. Если файл был создан, источником является /dev/null; если файл был удален, целью является /dev/null. Если вы установите diff.mnemonicPrefixпеременную конфигурации в TRUE, вместо a/и b/префиксов в этом заголовке две строки вы можете иметь вместо c/, i/, w/и o/как префиксы, соответственно к тому , что вы сравните; см. git-config (1)
Далее следуют один или несколько кусков различий; каждый блок показывает одну область, где файлы отличаются. Унифицированный формат блоков начинается со строки вроде
Это в формате @@ from-file-range to-file-range @@ [header]. Диапазон от файла находится в форме -<start line>,<number of lines>, и диапазон файла - +<start line>,<number of lines>. И стартовая строка, и количество строк относятся к положению и длине фрагмента в прообразе и постимейке соответственно. Если число строк не указано, это означает, что это 0.
Необязательный заголовок показывает функцию C, в которой происходит каждое изменение, если это файл C (как -pопция в GNU diff) или эквивалент, если таковой имеется, для других типов файлов.
Далее идет описание, где файлы отличаются. Общие для обоих файлов строки начинаются с пробела. Строки, которые на самом деле различаются между двумя файлами, имеют один из следующих символов индикатора в левом столбце печати:
'+' - здесь была добавлена строка в первый файл.
@ Geremia: Git использует эвристику на основе сходства для обнаружения переименования ... а также для перемещения кода и обнаружения копирования git blame -C -C, вот как это работает; это Git дизайнерское решение. Формат git diff просто показывает индекс сходства (или различий) для пользователя.
Якуб Наренбский
1
@Geremia: Точнее, [header]ближайший предшествующий, как с началом функции, которая предшествует ломоть. В большинстве случаев эта строка содержит имя функции, в которой находится фрагмент diff. Это настраивается с помощью diffатрибута gitattribute для драйвера diff и драйвера diff, включая xfuncnameпеременную конфигурации.
Якуб Наребски
1
@AnthonyGeoghegan: строки могут быть удалены (тогда количество строк в изображении равно 0) или добавлено (тогда количество строк в изображении равно 0).
Якуб Наребски
1
@KasunSiyambalapitiya: унифицированный формат diff, который использует Git (в отличие от формата diff контекста ^ [1]), не различает измененную строку и удаленную и добавленную строку. [1]: gnu.org/software/diffutils/manual/html_node/Context-Format.html
Якуб Наребски,
1
@ JakubNarębski: Количество строк по умолчанию равно 1, а не 0. Это так просто. На практике он отображается только как «-1» и / или «+1» для однострочных файлов, поскольку отсутствует контекст для отображения.
Гвидо Флор
68
@@ -1,2 +3,4 @@ часть различий
Эта часть заняла у меня некоторое время, чтобы понять, поэтому я создал минимальный пример.
Формат в основном такой же, как diff -uунифицированный diff.
Это для тех, кто еще не совсем понял. В @@ -1,6 +1,4 @@pls не читайте -1как minus oneили +1как plus oneвместо этого читайте это как line 1 to 6в старом (первом) файле. Обратите внимание, здесь - implies "old"не минус. Кстати, спасибо за разъяснения ... хааш.
dkjain
Исходя из этого, @@ -1,8 +1,9 @@ можно ли интерпретировать то, что на самом деле произошло. например, 1) добавлена одна строка 2) изменена одна строка, добавлена одна строка и т. д. Или это по-другому, так как должен быть способ получить их, поскольку git diff correclty определяет, какие строки были изменены в коде. Пожалуйста, помогите мне, так как мне действительно нужно разобраться с этим
Касун Сиямбалапития
Обратите внимание, что это неверно и очень вводит в заблуждение, это утверждение в ответе выше: « +1,4говорит, что этот фрагмент соответствует строки 1-4 второго файла ». Это связано с тем, что +1,4могут ссылаться на не зависящие от контекста строки. Скорее, на +1,4самом деле « » означает, что « в этой« версии »файла есть 4строки (т.е. строки контекста) . Важно понимать значение +, -и <whitespace>в начале этих строк, поскольку это относится к интерпретации фрагментов. Более наглядный пример: youtube.com/watch?v=1tqMjJeyKpw
Дамилола Оловуокер
23
Вот простой пример.
diff --git a/file b/file
index 10ff2df..84d4fa2 100644
--- a/file
+++ b/file
@@ -1,5 +1,5 @@
line1
line2
-this line will be deleted
line4
line5
+this line is added
--git это не команда, это означает, что это git-версия diff (не unix)
a/ b/каталоги, они не настоящие. это просто удобство, когда мы имеем дело с одним и тем же файлом (в моем случае a / находится в индексе, а b / в рабочем каталоге)
10ff2df..84d4fa2 идентификаторы BLOB-объектов этих 2 файлов
100644 это «биты режима», указывающие, что это обычный файл (не исполняемый и не символическая ссылка)
--- a/file +++ b/fileзнаки минус показывают строки в версии a /, но отсутствуют в версии b /; и знаки плюс показывают строки, отсутствующие в /, но присутствующие в b / (в моем случае --- означает удаленные строки, а +++ означает добавленные строки в b / и этот файл в рабочем каталоге)
@@ -1,5 +1,5 @@чтобы понять это, лучше работать с большим файлом; если у вас есть два изменения в разных местах, вы получите две записи, как @@ -1,5 +1,5 @@; Предположим, у вас есть файл line1 ... line100 и удаленный line10 и добавьте новый line100 - вы получите:
@@ -7,7 +7,6 @@ line6
line7
line8
line9
-this line10 to be deleted
line11
line12
line13
@@ -98,3 +97,4 @@ line97
line98
line99
line100
+this is new line100
Спасибо. «100644 - это биты режима, указывающие, что это обычный файл (не исполняемый и не символическая ссылка)». Является ли «биты режима» концепцией в Linux или только в Git?
Тим
@Tim Не относится к мерзавцу. Правые 3 цифры ( 644) должны быть прочитаны в восьмеричном виде (значения: 1, 2, 4 соответственно разрешения eXecute, Write и Read) и соответствуют в этом порядке Владельцу (Пользователь), затем Группе, затем Другим разрешениям. Таким образом, короче говоря, 644это означает, что если оно написано символически u=rw,og=r, оно доступно для чтения всем, но доступно только для владельца. Другие цифры слева кодируют другую информацию, например, если это символическая ссылка и т. Д. Значения можно увидеть github.com/git/git/blob/… , первая 1 в этой позиции - «обычный файл».
Патрик Мевзек
15
Формат вывода по умолчанию (который изначально исходит из программы, известной как « diffпоиск дополнительной информации») известен как «унифицированный diff». Он содержит по существу 4 различных типа линий:
контекстные строки, которые начинаются с одного пробела,
вставки линий , которые показывают линию , которая была вставлена, которые начинаются с +,
строки удаления, которые начинаются с -, и
строки метаданных, которые описывают вещи более высокого уровня, например, о каком файле идет речь, какие параметры использовались для генерации различий, менял ли файл свои разрешения и т. д.
Я советую вам практиковать чтение различий между двумя версиями файла, где вы точно знаете, что изменили. Таким образом, вы узнаете, что происходит, когда увидите это.
Отметка времени выглядит как `2002-02-21 23: 30: 39.942229878 -0800 ', чтобы указать дату, время с долями секунды и часовой пояс.
Вы можете изменить содержимое заголовка с помощью опции --lala = LABEL; см. * Примечание к альтернативным именам ::.
Далее следуют один или несколько кусков различий; каждый блок показывает одну область, где файлы отличаются. Единицы унифицированного формата выглядят так:
Общие для обоих файлов строки начинаются с пробела. Строки, которые на самом деле различаются между двумя файлами, имеют один из следующих символов индикатора в левом столбце печати:
Обратите внимание, что git не печатает часть «XXX-FILE-MODIFICATION-TIME», так как это не имеет смысла для системы контроля версий. Для сравнения файлов в файловой системе временные метки могут функционировать как контроль версий «бедняков».
Якуб Наребски
3
Из вашего вопроса неясно, какую часть различий вы находите непонятной: фактическую разность или дополнительную информацию заголовка, которую печатает git. На всякий случай вот краткий обзор шапки.
Первая строка выглядит примерно так diff --git a/path/to/file b/path/to/file- очевидно, она просто говорит вам, для какого файла предназначен этот раздел diff. Если вы установите логическую переменную конфигурации diff.mnemonic prefix, то aи bбудет изменено на более описательные буквы, такие как cи w(коммит и дерево работ).
Далее, есть «строки режима» - строки, дающие вам описание любых изменений, которые не связаны с изменением содержимого файла. Это включает новые / удаленные файлы, переименованные / скопированные файлы и изменения разрешений.
Наконец, есть такая строка index 789bd4..0afb621 100644. Вы, вероятно, никогда об этом не позаботитесь, но эти шестизначные шестнадцатеричные числа - это сокращенные SHA1-хэши старых и новых больших двоичных объектов для этого файла (большой двоичный объект - это git-объект, хранящий необработанные данные, например содержимое файла). И, конечно же, режим 100644файла - последние три цифры, очевидно, являются разрешениями; первые три дают дополнительную информацию о метаданных файла (так описывает сообщение ).
После этого вы переходите к стандартному унифицированному выводу различий (как в классическом diff -U). Он разделен на фрагменты - блок - это раздел файла, содержащий изменения и их контекст. Каждый ломоть предшествует парой ---и +++линий , обозначающего файл в вопросе, то фактический дифференциал есть (по умолчанию) трех строк контекста по обе стороны от -и +линий , показывающих удаленные / добавлены линии.
Ответы:
Давайте рассмотрим пример расширенного diff из истории git (в коммите 1088261f в репозитории git.git ):
Давайте проанализируем этот патч построчно.
Первая строка
это заголовок "git diff" в формеdiff --git a/file1 b/file2
.a/
Иb/
имена файлов являются одинаковыми , если переименовать / копировать не участвует (как в нашем случае). Это--git
означает, что diff находится в формате «git» diff.Далее идет одна или несколько расширенных строк заголовка. Первые три
скажите нам, что файл был переименован изbuiltin-http-fetch.c
вhttp-fetch.c
и что эти два файла идентичны на 95% (что использовалось для обнаружения этого переименования).Последняя строка в расширенном заголовке diff, который расскажите нам о режиме данного файла (это
100644
означает, что это обычный файл, а не, например, символическая ссылка, и что он не имеет исполняемого бита разрешения), и о сокращенном хеше preimage (версия файла перед данным изменением) и postimage ( версия файла после изменения). Эта строка используется,git am --3way
чтобы попытаться выполнить трехстороннее слияние, если патч не может быть применен сам по себе.Далее идет двухстрочный унифицированный заголовок diff
По сравнению сdiff -U
результатом он не имеет ни времени изменения файла, ни времени изменения файла после исходного (preimage) и конечного (postimage) имен файлов. Если файл был создан, источником является/dev/null
; если файл был удален, целью является/dev/null
.Если вы установите
diff.mnemonicPrefix
переменную конфигурации в TRUE, вместоa/
иb/
префиксов в этом заголовке две строки вы можете иметь вместоc/
,i/
,w/
иo/
как префиксы, соответственно к тому , что вы сравните; см. git-config (1)Далее следуют один или несколько кусков различий; каждый блок показывает одну область, где файлы отличаются. Унифицированный формат блоков начинается со строки вроде
или Это в формате@@ from-file-range to-file-range @@ [header]
. Диапазон от файла находится в форме-<start line>,<number of lines>
, и диапазон файла -+<start line>,<number of lines>
. И стартовая строка, и количество строк относятся к положению и длине фрагмента в прообразе и постимейке соответственно. Если число строк не указано, это означает, что это 0.Необязательный заголовок показывает функцию C, в которой происходит каждое изменение, если это файл C (как
-p
опция в GNU diff) или эквивалент, если таковой имеется, для других типов файлов.Далее идет описание, где файлы отличаются. Общие для обоих файлов строки начинаются с пробела. Строки, которые на самом деле различаются между двумя файлами, имеют один из следующих символов индикатора в левом столбце печати:
Так, например, первый кусок
означает, что
cmd_http_fetch
был замененmain
, и этаconst char *prefix;
строка была добавлена.Другими словами, перед изменением соответствующий фрагмент файла 'builtin-http-fetch.c' выглядел так:
После изменения этот фрагмент теперь файла http-fetch.c выглядит следующим образом:
Там может быть
строка присутствует (это не в примере diff).Как сказал Донал Феллоуз , лучше всего практиковаться в чтении различий на реальных примерах, где вы знаете, что вы изменили.
Ссылки:
источник
git blame -C -C
, вот как это работает; это Git дизайнерское решение. Формат git diff просто показывает индекс сходства (или различий) для пользователя.[header]
ближайший предшествующий, как с началом функции, которая предшествует ломоть. В большинстве случаев эта строка содержит имя функции, в которой находится фрагмент diff. Это настраивается с помощьюdiff
атрибута gitattribute для драйвера diff и драйвера diff, включаяxfuncname
переменную конфигурации.@@ -1,2 +3,4 @@
часть различийЭта часть заняла у меня некоторое время, чтобы понять, поэтому я создал минимальный пример.
Формат в основном такой же, как
diff -u
унифицированный diff.Например:
Здесь мы удалили строки 2, 3, 14 и 15. Вывод:
@@ -1,6 +1,4 @@
средства:-1,6
означает, что этот фрагмент первого файла начинается со строки 1 и показывает всего 6 строк. Поэтому он показывает строки с 1 по 6.-
означает «старый», как мы обычно называем этоdiff -u old new
.+1,4
означает, что этот фрагмент второго файла начинается со строки 1 и показывает всего 4 строки. Поэтому он показывает строки с 1 по 4.+
означает «новый».У нас только 4 строки вместо 6, потому что 2 строки были удалены! Новый кусок просто:
@@ -11,6 +9,4 @@
для второго куска аналогично:в старом файле у нас есть 6 строк, начиная со строки 11 старого файла:
в новом файле у нас есть 4 строки, начиная с 9 строки нового файла:
Обратите внимание, что строка
11
является 9-й строкой нового файла, потому что мы уже удалили 2 строки в предыдущем блоке: 2 и 3.Hunk header
В зависимости от вашей версии и конфигурации git, вы также можете получить строку кода рядом со
@@
строкой, например,func1() {
в:Это также можно получить с
-p
флагом равниныdiff
.Пример: старый файл:
Если мы удалим строку
6
, diff покажет:Обратите внимание, что это неправильная строка
func1
: пропущенные строки1
и2
.Эта удивительная особенность часто говорит точно, к какой функции или классу принадлежит каждый кусок, что очень полезно для интерпретации различий.
Как именно работает алгоритм выбора заголовка, обсуждается здесь: Откуда взята выдержка из заголовка git diff hunk?
источник
@@ -1,6 +1,4 @@
pls не читайте-1
какminus one
или+1
какplus one
вместо этого читайте это какline 1 to 6
в старом (первом) файле. Обратите внимание, здесь- implies "old"
не минус. Кстати, спасибо за разъяснения ... хааш.+1,4
говорит, что этот фрагмент соответствует строки 1-4 второго файла ». Это связано с тем, что+1,4
могут ссылаться на не зависящие от контекста строки. Скорее, на+1,4
самом деле « » означает, что « в этой« версии »файла есть4
строки (т.е. строки контекста) . Важно понимать значение+
,-
и<whitespace>
в начале этих строк, поскольку это относится к интерпретации фрагментов. Более наглядный пример: youtube.com/watch?v=1tqMjJeyKpwВот простой пример.
Вот объяснение (подробности см. Здесь ).
--git
это не команда, это означает, что это git-версия diff (не unix)a/ b/
каталоги, они не настоящие. это просто удобство, когда мы имеем дело с одним и тем же файлом (в моем случае a / находится в индексе, а b / в рабочем каталоге)10ff2df..84d4fa2
идентификаторы BLOB-объектов этих 2 файлов100644
это «биты режима», указывающие, что это обычный файл (не исполняемый и не символическая ссылка)--- a/file +++ b/file
знаки минус показывают строки в версии a /, но отсутствуют в версии b /; и знаки плюс показывают строки, отсутствующие в /, но присутствующие в b / (в моем случае --- означает удаленные строки, а +++ означает добавленные строки в b / и этот файл в рабочем каталоге)@@ -1,5 +1,5 @@
чтобы понять это, лучше работать с большим файлом; если у вас есть два изменения в разных местах, вы получите две записи, как@@ -1,5 +1,5 @@
; Предположим, у вас есть файл line1 ... line100 и удаленный line10 и добавьте новый line100 - вы получите:источник
644
) должны быть прочитаны в восьмеричном виде (значения: 1, 2, 4 соответственно разрешения eXecute, Write и Read) и соответствуют в этом порядке Владельцу (Пользователь), затем Группе, затем Другим разрешениям. Таким образом, короче говоря,644
это означает, что если оно написано символическиu=rw,og=r
, оно доступно для чтения всем, но доступно только для владельца. Другие цифры слева кодируют другую информацию, например, если это символическая ссылка и т. Д. Значения можно увидеть github.com/git/git/blob/… , первая 1 в этой позиции - «обычный файл».Формат вывода по умолчанию (который изначально исходит из программы, известной как «
diff
поиск дополнительной информации») известен как «унифицированный diff». Он содержит по существу 4 различных типа линий:+
,-
, иЯ советую вам практиковать чтение различий между двумя версиями файла, где вы точно знаете, что изменили. Таким образом, вы узнаете, что происходит, когда увидите это.
источник
На моем Mac:
info diff
затем выберите:Output formats
->Context
->Unified format
->Detailed Unified
:Или в режиме онлайн, введите diff для gnu по тому же пути:
источник
Из вашего вопроса неясно, какую часть различий вы находите непонятной: фактическую разность или дополнительную информацию заголовка, которую печатает git. На всякий случай вот краткий обзор шапки.
Первая строка выглядит примерно так
diff --git a/path/to/file b/path/to/file
- очевидно, она просто говорит вам, для какого файла предназначен этот раздел diff. Если вы установите логическую переменную конфигурацииdiff.mnemonic prefix
, тоa
иb
будет изменено на более описательные буквы, такие какc
иw
(коммит и дерево работ).Далее, есть «строки режима» - строки, дающие вам описание любых изменений, которые не связаны с изменением содержимого файла. Это включает новые / удаленные файлы, переименованные / скопированные файлы и изменения разрешений.
Наконец, есть такая строка
index 789bd4..0afb621 100644
. Вы, вероятно, никогда об этом не позаботитесь, но эти шестизначные шестнадцатеричные числа - это сокращенные SHA1-хэши старых и новых больших двоичных объектов для этого файла (большой двоичный объект - это git-объект, хранящий необработанные данные, например содержимое файла). И, конечно же, режим100644
файла - последние три цифры, очевидно, являются разрешениями; первые три дают дополнительную информацию о метаданных файла (так описывает сообщение ).После этого вы переходите к стандартному унифицированному выводу различий (как в классическом
diff -U
). Он разделен на фрагменты - блок - это раздел файла, содержащий изменения и их контекст. Каждый ломоть предшествует парой---
и+++
линий , обозначающего файл в вопросе, то фактический дифференциал есть (по умолчанию) трех строк контекста по обе стороны от-
и+
линий , показывающих удаленные / добавлены линии.источник
index
строки. Подтвержденоgit hash-object ./file