Используя git diff, как я могу получить добавленные и измененные номера строк?
Предполагая, что у меня есть текстовый файл
alex
bob
matrix
will be removed
git repo
и я обновил его как
alex
new line here
another new line
bob
matrix
git
Здесь я добавил номер строки (2,3) и обновленный номер строки (6)
Как я могу получить данные этих номеров строк с помощью git diff или любой другой команды git?
Ответы
Ответ 1
git diff --stat
покажет вам результат, который вы получаете при передаче материала, на который вы ссылаетесь, я думаю.
git diff --stat
Чтобы точно показать номера строк, которые были изменены, вы можете использовать
git blame -p <file> | grep "Not Committed Yet"
И изменившаяся строка будет последним числом перед конечной скобкой в результате. Не чистое решение: (
Ответ 2
Здесь функция bash для вычисления полученных номеров строк из diff:
diff-lines() {
local path=
local line=
while read; do
esc=$'\033'
if [[ $REPLY =~ ---\ (a/)?.* ]]; then
continue
elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then
path=${BASH_REMATCH[2]}
elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then
line=${BASH_REMATCH[2]}
elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
echo "$path:$line:$REPLY"
if [[ ${BASH_REMATCH[2]} != - ]]; then
((line++))
fi
fi
done
}
Он может производить вывод, например:
$ git diff | diff-lines
http-fetch.c:1: #include "cache.h"
http-fetch.c:2: #include "walker.h"
http-fetch.c:3:
http-fetch.c:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
http-fetch.c:4:+int main(int argc, const char **argv)
http-fetch.c:5: {
http-fetch.c:6:+ const char *prefix;
http-fetch.c:7: struct walker *walker;
http-fetch.c:8: int commits_on_stdin = 0;
http-fetch.c:9: int commits;
http-fetch.c:19: int get_verbosely = 0;
http-fetch.c:20: int get_recover = 0;
http-fetch.c:21:
http-fetch.c:22:+ prefix = setup_git_directory();
http-fetch.c:23:+
http-fetch.c:24: git_config(git_default_config, NULL);
http-fetch.c:25:
http-fetch.c:26: while (arg < argc && argv[arg][0] == '-') {
fetch.h:1: #include "config.h"
fetch.h:2: #include "http.h"
fetch.h:3:
fetch.h:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix);
fetch.h:4:+int main(int argc, const char **argv);
fetch.h:5:
fetch.h:6: void start_fetch(const char* uri);
fetch.h:7: bool fetch_succeeded(int status_code);
из такого типа:
$ git diff
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/fetch.h b/fetch.h
index 5fd3e65..d43e0ca 100644
--- a/fetch.h
+++ b/fetch.h
@@ -1,7 +1,7 @@
#include "config.h"
#include "http.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix);
+int main(int argc, const char **argv);
void start_fetch(const char* uri);
bool fetch_succeeded(int status_code);
Если вы хотите показывать только добавленные/удаленные/измененные строки, а не окружающий контекст, вы можете передать -U0
в git diff:
$ git diff -U0 | diff-lines
http-fetch.c:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
http-fetch.c:4:+int main(int argc, const char **argv)
http-fetch.c:6:+ const char *prefix;
http-fetch.c:22:+ prefix = setup_git_directory();
http-fetch.c:23:+
fetch.h:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix);
fetch.h:4:+int main(int argc, const char **argv);
Он устойчив к цветовым кодам ANSI, поэтому вы можете передать --color=always
в git diff, чтобы получить обычное цветовое кодирование для добавленных/удаленных строк.
Выход может быть легко grepped:
$ git diff -U0 | diff-lines | grep 'main'
http-fetch.c:4:+int main(int argc, const char **argv)
fetch.h:4:+int main(int argc, const char **argv);
В вашем случае git diff -U0
даст:
$ git diff -U0 | diff-lines
test.txt:2:+new line here
test.txt:3:+another new line
test.txt:6:-will be removed
test.txt:6:-git repo
test.txt:6:+git
Если вам просто нужны номера строк, измените echo "$path:$line:$REPLY"
на просто echo "$line"
и проведите вывод через uniq
.
Ответ 3
Я использую --unified=0
вариант git diff
.
Например, git diff --unified=0 commit1 commit2
выводит diff:
![*enter image description here*]()
Из-за параметра --unified=0
на выходе diff отображается 0 строк контекста; другими словами, он показывает точно измененные строки.
Теперь вы можете определить строки, начинающиеся с '@@', и проанализировать их на основе шаблона:
@@ -startline1,count1 +startline2,count2 @@
Вернемся к приведенному выше примеру, для файла WildcardBinding.java, начиная с строки 910, удаляются 0 строк. Начните с строки 911, добавьте 4 строки.
Ответ 4
У меня была такая же проблема, поэтому я написал gawk script, который изменяет вывод git diff для добавления номера строки для каждой строки. Я считаю это полезным иногда, когда мне нужно развернуть рабочее дерево, хотя оно не ограничивается этим. Может быть, это кому-то полезно?
$ git diff HEAD~1 |showlinenum.awk
diff --git a/doc.txt b/doc.txt
index fae6176..6ca8c26 100644
--- a/doc.txt
+++ b/doc.txt
@@ -1,3 +1,3 @@
1: red
2: blue
:-green
3:+yellow
Вы можете скачать его здесь:
https://github.com/jay/showlinenum
Ответ 5
Номера строк всех незафиксированных строк (добавлены/изменены):
git blame <file> | grep -n '^0\{8\} ' | cut -f1 -d:
Пример вывода:
1
2
8
12
13
14
Ответ 6
Настройте внешний инструмент сравнения, который покажет вам номера строк. Например, это то, что у меня есть в моей глобальной конфигурации git:
diff.guitool=kdiff3
difftool.kdiff3.path=c:/Program Files (x86)/KDiff3/kdiff3.exe
difftool.kdiff3.cmd="c:/Program Files (x86)/KDiff3/kdiff3.exe" "$LOCAL" "$REMOTE"
См. этот ответ для более подробной информации: fooobar.com/questions/2689/...
Ответ 7
Здесь функция bash, которую я объединил:
echo ${f}:
for n in $(git --no-pager blame --line-porcelain $1 |
awk '/author Not Committed Yet/{if (a && a !~ /author Not Committed Yet/) print a} {a=$0}' |
awk '{print $3}') ; do
if (( prev_line > -1 )) ; then
if (( "$n" > (prev_line + 1) )) ; then
if (( (prev_line - range_start) > 1 )) ; then
echo -n "$range_start-$prev_line,"
else
echo -n "$range_start,$prev_line,"
fi
range_start=$n
fi
else
range_start=$n
fi
prev_line=$n
done
if (( "$range_start" != "$prev_line" )) ; then
echo "$range_start-$prev_line"
else
echo "$range_start"
fi
И это выглядит следующим образом:
views.py:
403,404,533-538,546-548,550-552,554-559,565-567,580-582
Ответ 8
Не совсем то, о чем вы просили, но git blame TEXTFILE
может помочь.
Ответ 9
Вы можете использовать git diff
в сочетании с параметром shortstat
, чтобы просто показать строки нет.
В случае отсутствия строк (в файле, который уже находится в репо) с момента последнего фиксации
git diff HEAD --shortstat
Он выведет что-то похожее на
1 file changed, 4 insertions(+)
Ответ 10
Это, вероятно, довольно точное количество измененных строк:
git diff --word-diff <commit> |egrep '(?:\[-)|(?:\{\+)' |wc -l
Кроме того, вот решение для номеров строк в вашем diff: https://github.com/jay/showlinenum