Zakładając, że mam plik tekstowy
alex
bob
matrix
will be removed
git repo
i zaktualizowałem go, aby był
alex
new line here
another new line
bob
matrix
git
Tutaj dodałem numer linii (2,3) i zaktualizowałem numer linii (6)
Jak mogę uzyskać informacje o tych numerach linii za pomocą git diff lub innego polecenia git?
Oto funkcja bash do obliczania wynikowych numerów wierszy z różnicy:
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 }
Może generować dane wyjściowe, takie jak:
z różnicy, takiej jak ta:
Jeśli chcesz pokazać tylko dodane / usunięte / zmodyfikowane linie, a nie otaczający kontekst, możesz przekazać
-U0
do git diff:Jest odporny na kody kolorów ANSI, więc możesz przejść
--color=always
do git diff, aby uzyskać zwykłe kodowanie kolorów dla dodanych / usuniętych linii.Wynik można łatwo grepować:
W twoim przypadku
git diff -U0
dałoby:Jeśli chcesz tylko numery linii, zmień na
echo "$path:$line:$REPLY"
justecho "$line"
i potokuj wyjścieuniq
.źródło
git diff --color
nie przechodzą. A może myślisz, że byłoby lepiej po prostu dodać ucieczki koloru do powrotu z tej funkcji?git diff --color | diff-lines
teraz działa zgodnie z oczekiwaniami :)zsh: parse error near `]+m'
jakieś pomysły? Błąd pochodzi z tej linii:elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
Korzystam z
--unified=0
opcjigit diff
.Na przykład
git diff --unified=0 commit1 commit2
wyświetla różnicę:Ze względu na tę
--unified=0
opcję, wyjście diff pokazuje 0 linii kontekstu; innymi słowy, pokazuje dokładnie zmienione linie .Teraz możesz zidentyfikować wiersze zaczynające się od „@@” i przeanalizować je na podstawie wzorca:
@@ -startline1,count1 +startline2,count2 @@
Wracając do powyższego przykładu, dla pliku WildcardBinding.java, zacznij od wiersza 910, usuwanych jest 0 wierszy. Zacznij od linii 911, dodawane są 4 linie.
źródło
@@ -910,10,+911,15@@
lub coś, to jak dokładnie określimy, ile wierszy jest dodawanych,Miałem ten sam problem, więc napisałem skrypt gawk, który zmienia wynik działania git diff tak, aby poprzedzał numer linii dla każdej linii. Uważam to za przydatne czasami, gdy potrzebuję porównać drzewo robocze, chociaż nie jest to ograniczone do tego. Może komuś się tutaj przyda?
Możesz go pobrać stąd:
https://github.com/jay/showlinenum
źródło
git diffn
aby to zrobić, i w pełni zachowuje kolory terminala i pokazuje numery wierszy zarówno starego pliku po lewej, jak i nowego pliku po prawej.Numery wierszy wszystkich niezatwierdzonych wierszy (dodane / zmodyfikowane):
Przykładowe dane wyjściowe:
źródło
Skonfiguruj zewnętrzne narzędzie porównujące, które pokaże numery linii. Na przykład to jest to, co mam w mojej globalnej konfiguracji git:
Zobacz tę odpowiedź, aby uzyskać więcej informacji: https://stackoverflow.com/q/949242/526535
źródło
Oto funkcja bash, którą zebrałem razem:
I wygląda to tak:
źródło
Jest to prawdopodobnie dość dokładna liczba zmienionych linii:
Również tutaj jest rozwiązanie dla numerów linii w twoim diff: https://github.com/jay/showlinenum
źródło
Nie jest to dokładnie to, o co prosiłeś, ale
git blame TEXTFILE
może pomóc.źródło
Możesz użyć w
git diff
połączeniu zshortstat
parametrem, aby po prostu pokazać liczbę zmienionych linii.Dla liczby linii zmienionych (w pliku, który jest już w repozytorium) od ostatniego zatwierdzenia
Wyświetli coś podobnego do
źródło
Szukałem sposobu, aby wyświetlić tylko te wiersze zmienione dla każdego pliku za pomocą git diff. Moim pomysłem było przekazanie tego wyjścia do lintera w celu sprawdzenia typu. To mi pomogło
źródło
Oto trochę Python copypasta, aby uzyskać numery linii dla zmodyfikowanych / usuniętych linii, na wypadek gdybyś natknął się na to pytanie, szukając tego.
Powinno być dość łatwo zmodyfikować go w coś, co pobiera również zmodyfikowane i dodane numery linii.
Testowałem tylko w systemie Windows, ale powinien również działać na wielu platformach.
import re import subprocess def main(file1: str, file2: str): diff = get_git_diff(file1, file2) print(edited_lines(diff)) def edited_lines(git_diff: str): ans = [] diff_lines = git_diff.split("\n") found_first = False # adjust for added lines adjust = 0 # how many lines since the start count = 0 for line in diff_lines: if found_first: count += 1 if line.startswith('-'): # minus one because count is 1 when we're looking at the start line ans.append(start + count - adjust - 1) continue if line.startswith('+'): adjust += 1 continue # get the start line match = re.fullmatch(r'@@ \-(\d+),\d+ \+\d+,\d+ @@', line) if match: start = int(match.group(1)) count = 0 adjust = 0 found_first = True return ans def get_git_diff(file1: str, file2: str): try: diff_process: subprocess.CompletedProcess = subprocess.run(['git', 'diff', '--no-index', '-u', file1, file2], shell=True, check=True, stdout=subprocess.PIPE) ans = diff_process.stdout # git may exit with 1 even though it worked except subprocess.CalledProcessError as e: if e.stdout and e.stderr is None: ans = e.stdout else: raise # remove carriage at the end of lines from Windows ans = ans.decode() ans.replace('\r', '') return ans if __name__ == "__main__": main("file1.txt", "file2.txt")
źródło