Jak sprawić, aby git oznaczył usunięty i nowy plik jako przeniesienie pliku?
505
Przeniesiłem plik ręcznie, a następnie zmodyfikowałem go. Według Git jest to nowy plik i plik usunięty. Czy jest jakiś sposób, aby zmusić Gita do traktowania go jako przeniesienia pliku?
Dla danego pliku old_file.txt, a następnie git mv old_file.txt new_file.txtodpowiada git rm --cached old_file.txt, mv old_file.txt new_file.txt, git add new_file.txt.
Jarl
3
Jarl: nie, nie jest. Jeśli w pliku są również zmiany, git mvnie doda ich do pamięci podręcznej, ale git addzrobi to. Wolę przenieść plik z powrotem, aby móc go użyć git mv, a następnie git add -pprzejrzeć mój zestaw zmian.
Git poprawił się w ciągu ostatnich 8 lat, jeśli jest to tylko jeden plik, najlepsza odpowiedź stackoverflow.com/a/433142/459 nic nie zrobiła… ale możesz śledzić stackoverflow.com/a/1541072/459, aby uzyskać aktualizację / dodać do statusu mv / modyfikuj.
dlamblin,
Odpowiedzi:
435
Git automatycznie wykryje przeniesienie / zmianę nazwy, jeśli modyfikacja nie jest zbyt poważna. Tylko git addnowy plik i git rmstary plik. git statuspokaże wtedy, czy wykrył zmianę nazwy.
dodatkowo w przypadku przemieszczania się po katalogach może być konieczne:
cd na początek tej struktury katalogów.
Biegać git add -A .
Uruchom, git statusaby sprawdzić, czy „nowy plik” jest teraz plikiem o zmienionej nazwie
Jeśli status git nadal pokazuje „nowy plik”, a nie „przemianowano”, musisz postępować zgodnie z radą Hanka Gaya, wykonać ruch i zmodyfikować w dwóch osobnych zatwierdzeniach.
Wyjaśnienie: „niezbyt poważny” oznacza, że nowy plik i stary plik są w 50% „podobne” na podstawie niektórych indeksów podobieństwa używanych przez git.
pjz
151
Coś, co rozłączyło mnie na kilka minut: jeśli pliki o zmienionej nazwie i pliki usunięte nie zostaną ustawione do zatwierdzenia, pojawią się one jako usunięte i nowy plik. Po dodaniu ich do indeksu pomostowego rozpozna to jako zmianę nazwy.
marczych
19
Warto wspomnieć, że mówiąc o „ Git automatycznie wykryje ruch / zmianę nazwy ”. Czyni to w momencie wykorzystać git status, git logalbo git diff, nie w momencie robisz git add, git mvalbo git rm. Mówiąc dalej o wykrywaniu zmiany nazwy, ma to sens tylko w przypadku plików przemieszczanych. Zatem git mvzmiana pliku może wyglądać git statustak, jakby uważała go za plik rename, ale kiedy użyjesz git stage(tak jak git add) pliku, staje się jasne, że zmiana jest zbyt duża, aby można go było wykryć jako zmianę nazwy.
Jarl
5
Prawdziwym kluczem wydaje się być dodanie zarówno nowej, jak i starej lokalizacji w tym samym miejscu git add, co, jak sugeruje @ jrhorn424, powinno prawdopodobnie stanowić po prostu całe repo.
brianary
4
Nie jest to jednak nieomylne, szczególnie jeśli plik się zmienił i jest mały. Czy istnieje metoda, aby konkretnie powiedzieć gitowi o ruchu?
Rebs
112
Wykonaj ruch i modyfikuj w osobnych zatwierdzeniach.
Rozumiem, że Git potrafi jednocześnie obsługiwać ruchy i modyfikacje. Podczas programowania w Javie i używania IDE zmiana nazwy klasy jest zarówno modyfikacją, jak i posunięciem. Rozumiem, że Git powinien nawet być w stanie automatycznie dowiedzieć się, kiedy nastąpi ruch (z usunięcia i stworzenia).
pupeno
1
Perl też tego wymaga i nigdy nie miałem, aby Git wykrył ruch / zmianę nazwy.
jrockway
10
@jrockway, miałem. Zdarza się łatwo z małymi plikami, wydaje mi się, że „stają się one” zbyt różne, aby oznaczać ruch ”.
ANeves
2
Czy można to zrobić automatycznie? Mam wiele plików w indeksie, chcę najpierw zatwierdzić przeniesienie, a następnie zmianę, ale trudno to zrobić ręcznie
ReDetection
5
Należy zauważyć, że jeśli git diffnie rozpozna zmiany nazwy w jednym zatwierdzeniu, nie rozpozna go w dwóch zatwierdzeniach. Aby to zrobić, musisz użyć -Maka --find-renames. Więc jeśli motywacją, która doprowadziła cię do tego pytania, jest zobaczenie zmiany nazwy w żądaniu ściągnięcia (mówienie z doświadczenia), podzielenie jej na dwie zmiany nie doprowadzi cię do tego celu.
mattliu
44
To wszystko jest kwestią percepcyjną. Git jest ogólnie dość dobry w rozpoznawaniu ruchów, ponieważ GIT jest narzędziem do śledzenia zawartości
Wszystko, co tak naprawdę zależy, to sposób, w jaki wyświetla się „stat”. Jedyną różnicą jest tutaj flaga -M.
Przepraszam, jeśli wydaje się to trochę pedantyczne, ale „Git jest ogólnie dość dobry w rozpoznawaniu ruchów, ponieważ GIT jest narzędziem do śledzenia zawartości” wydaje mi się, że nie jest sekwencją. Tak, jest to moduł do śledzenia zawartości i być może jest dobry w wykrywaniu ruchów, ale jedno zdanie tak naprawdę nie wynika z drugiego. Tylko dlatego, że jest to moduł do śledzenia zawartości, wykrywanie ruchu niekoniecznie jest dobre. W rzeczywistości moduł do śledzenia zawartości może w ogóle nie wykrywać ruchu.
Laurence Gonsalves,
1
@WarrenSeine po zmianie nazwy katalogu SHA1 plików w tym katalogu nie zmieniają się. Wszystko, co masz, to nowy obiekt DRZEWO z tymi samymi SHA1. Nie ma powodu, dla którego zmiana nazwy katalogu spowodowałaby znaczne zmiany danych.
Kent Fredric
1
@KentFredric Pokazałeś, że używając -M z „git logiem” możemy sprawdzić, czy nazwa pliku została zmieniona, czy też nie, wypróbowałem go i działa dobrze, ale kiedy opublikuję mój kod do sprawdzenia i zobaczę ten plik w gerrit ( gerritcodereview.com ) tam pokazuje, że plik został nowo dodany, a poprzedni został usunięty. Czy istnieje opcja w „git commit”, za pomocą której wykonuję i gerrit pokazuje to poprawnie.
Patrick,
1
Nie. W ogóle tego nie pokazałem. Pokazałem, że Git może udawać, że add + delete to zmiana nazwy, ponieważ treść jest taka sama. Nie ma sposobu, aby wiedzieć, co się stało, i to nie obchodzi. Wszystko, co pamięta git, jest „dodane” i „usunięte”. „Zmiana nazwy” nigdy nie jest nagrywana.
Kent Fredric,
1
Na przykład ostatnio zrobiłem dużo „Kopiuj + Edytuj” na repozytorium. Większość sposobów przeglądania to tylko „nowy plik”, ale jeśli przejdziesz git log -M1 -C1 -B1 -D --find-copies-harder, git może „odkryć”, że nowy plik mógł zostać skopiowany jako pierwszy. Czasami robi to dobrze, innym razem znajduje całkowicie niepowiązane pliki, które miały identyczną zawartość.
Kent Fredric,
36
git diff -Mlub git log -Mpowinien automatycznie wykryć takie zmiany jako zmianę nazwy z niewielkimi zmianami, o ile rzeczywiście są. Jeśli Twoje drobne zmiany nie są niewielkie, możesz zmniejszyć trzykrotne podobieństwo, np
Oto szybkie i brudne rozwiązanie dla jednego lub kilku plików o zmienionej nazwie i zmodyfikowanych, które nie zostały zatwierdzone.
Powiedzmy, że plik został nazwany, fooa teraz nazywa się bar:
Zmień nazwę barna tymczasową nazwę:
mv bar side
Zamówienie foo:
git checkout HEAD foo
Zmień nazwę foona barGit:
git mv foo bar
Teraz zmień nazwę pliku tymczasowego z powrotem na bar.
mv side bar
Ten ostatni krok przywraca zmienioną zawartość do pliku.
Chociaż może to zadziałać, jeśli przeniesiony plik ma zbyt inną zawartość niż oryginalny git, uzna, że skuteczniej jest zdecydować, że jest to nowy obiekt. Pokażę:
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ git add README.md work.js # why are the changes unstaged, let's add them.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ git stash # what? let's go back a bit
Saved working directory and index state WIP on dir: f7a8685 update
HEAD is now at f7a8685 update
$ git status
On branch workit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.idea/
nothing added to commit but untracked files present (use "git add" to track)
$ git stash pop
Removing README
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: README
modified: work.js
Dropped refs/stash@{0} (1ebca3b02e454a400b9fb834ed473c912a00cd2f)
$ git add work.js
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: README
$ git add README # hang on, I want it removed
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ mv README.md Rmd # Still? Try the answer I found.
$ git checkout README
error: pathspec 'README' did not match any file(s) known to git.
$ git checkout HEAD README # Ok the answer needed fixing.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: README.md
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ git mv README README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ mv Rmd README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ # actually that's half of what I wanted; \
# and the js being modified twice? Git prefers it in this case.
Ten proces jest bezcelowy. git nie dodaje żadnych metadanych dla nazw, git mvjest po prostu wygodą dla pary git rm/ git addpary. Jeśli już zrobiłeś 'mv bar foo', wszystko, co musisz zrobić, to upewnić się, że dokonałeś zatwierdzenia git add fooi git rm barprzed nim. Można to zrobić tak samo, jak pojedyncze git add -Apolecenie lub git add foo; git commit -asekwencję.
CB Bailey,
17
Wiem tylko, że zanim to zrobiłem, Git nie rozpoznał tego jako ruchu. Po tym, jak to zrobiłem, Git rozpoznał to jako ruch.
8
Rozpoznaje to jako ruch. Ale teraz ma też tę zmianę, że nie jest wystawiana. Po addponownym utworzeniu pliku git przerywa przenoszenie / modyfikację do usuniętego / dodanego ponownie.
Michael Piefel
4
Ten proces będzie działał, jeśli wykonasz git commitkrok 3, w przeciwnym razie będzie niepoprawny. Ponadto @CharlesBailey ma rację, możesz równie łatwo wykonać normalną mv blah fooczynność w kroku 3, a następnie zatwierdzić i uzyskać te same wyniki.
DaFlame
5
„Ten proces jest bezcelowy”. - Służy to celowi, gdy git się pomylił i myśli, że plik został usunięty, a dodano inny plik. To usuwa zamieszanie Gita i oznacza plik jako jawnie przeniesiony bez konieczności wykonywania pośrednich zatwierdzeń.
Danack
20
Jeśli mówisz o git statusnie pokazywaniu nazw, spróbuj git commit --dry-run -azamiast tego
Jeśli używasz TortoiseGit, ważne jest, aby pamiętać, że automatyczne wykrywanie zmiany nazwy Gita ma miejsce podczas zatwierdzania, ale fakt, że tak się stanie, nie zawsze jest wcześniej wyświetlany przez oprogramowanie. Przeniosłem dwa pliki do innego katalogu i dokonałem niewielkich zmian. Używam TortoiseGit jako mojego narzędzia do zatwierdzania, a lista wprowadzonych zmian pokazała, że pliki są usuwane i dodawane, a nie przenoszone. Uruchomienie statusu git z wiersza poleceń pokazało podobną sytuację. Jednak po zatwierdzeniu plików pojawiły się w dzienniku jako przemianowane. Tak więc odpowiedź na twoje pytanie jest taka, o ile nie zrobiłeś nic zbyt drastycznego, Git powinien automatycznie zmienić nazwę.
Edycja: Najwyraźniej jeśli dodasz nowe pliki, a następnie wykonasz status git z wiersza poleceń, zmiana nazwy powinna pojawić się przed zatwierdzeniem.
Edycja 2: Ponadto, w TortoiseGit, dodaj nowe pliki w oknie dialogowym zatwierdzenia, ale ich nie zatwierdzaj. Następnie, jeśli przejdziesz do polecenia Pokaż dziennik i spojrzysz na katalog roboczy, zobaczysz, czy Git wykrył zmianę nazwy przed zatwierdzeniem.
To samo pytanie zostało zadane tutaj: https://tortoisegit.org/issue/1389 i zostało zarejestrowane jako błąd do naprawy tutaj: https://tortoisegit.org/issue/1440 Okazuje się, że jest to problem z wyświetlaniem w zatwierdzeniu TortoiseGit dialog, a także istnieje w stanie git, jeśli nie dodałeś nowych plików.
Masz rację, nawet jeśli TortoiseGit pokazuje usuń + dodaj, nawet jeśli status git pokazuje usuń + dodaj, nawet jeśli git commit - suche uruchomienie pokazuje usuń + dodaj, po git commit widzę zmianę nazwy, a nie usuwanie + dodawanie.
Tomas Kubes
1
Jestem prawie pewien, że automatyczne wykrywanie zmiany nazwy ma miejsce podczas wyszukiwania historii ; w zatwierdzeniu jest to zawsze dodawanie + usuwanie. To wyjaśnia również opisywane przez ciebie schizofreniczne zachowania. Stąd opcje tutaj: stackoverflow.com/a/434078/155892
Mark Sowul
10
Albo możesz spróbować odpowiedzieć na to pytanie tutaj przez Amber ! Cytując to jeszcze raz:
Najpierw anuluj dodawanie etapowe dla ręcznie przeniesionego pliku:
Oczywiście, jeśli już dokonałeś ręcznego przenoszenia, możesz zamiast tego zresetować wersję przed przeniesieniem, a następnie po prostu pobrać stamtąd mv.
Ostatnio miałem ten problem podczas przenoszenia (ale nie modyfikowania) niektórych plików.
Problem polega na tym, że Git zmienił niektóre zakończenia linii, gdy przenosiłem pliki, a następnie nie był w stanie stwierdzić, że pliki były takie same.
Korzystanie git mvz rozwiązania problemu, ale działa tylko na pojedyncze pliki / katalogi, a ja miałem wiele plików w katalogu głównym repozytorium do zrobienia.
Jednym ze sposobów naprawienia tego byłoby użycie magii typu bash / batch.
Inny sposób jest następujący
Przenieś pliki i git commit. To aktualizuje zakończenia linii.
Przenieś pliki z powrotem do ich oryginalnej lokalizacji, teraz, gdy mają nowe zakończenia linii i git commit --amend
Przenieś pliki ponownie i git commit --amend. Tym razem nie ma zmian w zakończeniach linii, więc Git jest szczęśliwy
Dla mnie zadziałało przechowywanie wszystkich zmian przed zatwierdzeniem i wyskakiwanie ich ponownie. To spowodowało, że git ponownie przeanalizował dodane / usunięte pliki i poprawnie oznaczył je jako przeniesione.
Jest na to prawdopodobnie lepszy sposób „wiersza poleceń” i wiem, że to hack, ale nigdy nie byłem w stanie znaleźć dobrego rozwiązania.
Korzystanie z TortoiseGIT: Jeśli masz zatwierdzenie GIT, w którym niektóre operacje przenoszenia plików są wyświetlane jako ładunek dodawania / usuwania zamiast zmiany nazw, nawet jeśli pliki mają tylko niewielkie zmiany, wykonaj następujące czynności:
Sprawdź, co zrobiłeś lokalnie
Sprawdź zmianę mini-liniową w drugim zatwierdzeniu
Idź do GIT zaloguj się żółw git
Wybierz dwa zatwierdzenia, kliknij prawym przyciskiem myszy i wybierz „scal w jeden zatwierdzenie”
Nowe zatwierdzenie będzie teraz poprawnie wyświetlało nazwy plików… co pomoże utrzymać właściwą historię plików.
Kiedy jednocześnie edytuję, zmieniam nazwę i przenoszę plik, żadne z tych rozwiązań nie działa. Rozwiązaniem jest zrobienie tego w dwóch zatwierdzeniach (edycja i zmiana nazwy / przeniesienie osobno), a następnie fixupw drugim zatwierdzeniu za pomocą git rebase -ijednego zatwierdzenia.
Rozumiem to pytanie: „Jak sprawić, aby git rozpoznał usunięcie starego pliku i utworzenie nowego pliku jako przeniesienie pliku”.
Tak w katalogu roboczym po usunięciu starego pliku i wstawieniu starego pliku, git statuspowie „ deleted: old_file” i „ Untracked files: ... new_file”
Ale w indeksie pomostowym / poziomie po dodaniu i usunięciu pliku za pomocą git zostanie rozpoznany jako przeniesienie pliku. Aby to zrobić, zakładając, że wykonałeś usuwanie i tworzenie za pomocą swojego systemu operacyjnego, podaj następujące polecenia:
git add new_file
git rm old_file
Jeśli zawartość pliku jest w 50% lub więcej podobna, uruchomiona git statuskomenda powinna dać ci:
old_file.txt
, a następniegit mv old_file.txt new_file.txt
odpowiadagit rm --cached old_file.txt
,mv old_file.txt new_file.txt
,git add new_file.txt
.git mv
nie doda ich do pamięci podręcznej, alegit add
zrobi to. Wolę przenieść plik z powrotem, aby móc go użyćgit mv
, a następniegit add -p
przejrzeć mój zestaw zmian.Odpowiedzi:
Git automatycznie wykryje przeniesienie / zmianę nazwy, jeśli modyfikacja nie jest zbyt poważna. Tylko
git add
nowy plik igit rm
stary plik.git status
pokaże wtedy, czy wykrył zmianę nazwy.dodatkowo w przypadku przemieszczania się po katalogach może być konieczne:
git add -A .
git status
aby sprawdzić, czy „nowy plik” jest teraz plikiem o zmienionej nazwieJeśli status git nadal pokazuje „nowy plik”, a nie „przemianowano”, musisz postępować zgodnie z radą Hanka Gaya, wykonać ruch i zmodyfikować w dwóch osobnych zatwierdzeniach.
źródło
git status
,git log
albogit diff
, nie w momencie robiszgit add
,git mv
albogit rm
. Mówiąc dalej o wykrywaniu zmiany nazwy, ma to sens tylko w przypadku plików przemieszczanych. Zatemgit mv
zmiana pliku może wyglądaćgit status
tak, jakby uważała go za plikrename
, ale kiedy użyjeszgit stage
(tak jakgit add
) pliku, staje się jasne, że zmiana jest zbyt duża, aby można go było wykryć jako zmianę nazwy.git add
, co, jak sugeruje @ jrhorn424, powinno prawdopodobnie stanowić po prostu całe repo.Wykonaj ruch i modyfikuj w osobnych zatwierdzeniach.
źródło
git diff
nie rozpozna zmiany nazwy w jednym zatwierdzeniu, nie rozpozna go w dwóch zatwierdzeniach. Aby to zrobić, musisz użyć-M
aka--find-renames
. Więc jeśli motywacją, która doprowadziła cię do tego pytania, jest zobaczenie zmiany nazwy w żądaniu ściągnięcia (mówienie z doświadczenia), podzielenie jej na dwie zmiany nie doprowadzi cię do tego celu.To wszystko jest kwestią percepcyjną. Git jest ogólnie dość dobry w rozpoznawaniu ruchów, ponieważ GIT jest narzędziem do śledzenia zawartości
Wszystko, co tak naprawdę zależy, to sposób, w jaki wyświetla się „stat”. Jedyną różnicą jest tutaj flaga -M.
git log --stat -M
git log --stat
git help log
źródło
git log -M1 -C1 -B1 -D --find-copies-harder
, git może „odkryć”, że nowy plik mógł zostać skopiowany jako pierwszy. Czasami robi to dobrze, innym razem znajduje całkowicie niepowiązane pliki, które miały identyczną zawartość.git diff -M
lubgit log -M
powinien automatycznie wykryć takie zmiany jako zmianę nazwy z niewielkimi zmianami, o ile rzeczywiście są. Jeśli Twoje drobne zmiany nie są niewielkie, możesz zmniejszyć trzykrotne podobieństwo, npzmniejszyć go z domyślnych 50% do 20%.
źródło
Oto szybkie i brudne rozwiązanie dla jednego lub kilku plików o zmienionej nazwie i zmodyfikowanych, które nie zostały zatwierdzone.
Powiedzmy, że plik został nazwany,
foo
a teraz nazywa siębar
:Zmień nazwę
bar
na tymczasową nazwę:Zamówienie
foo
:Zmień nazwę
foo
nabar
Git:Teraz zmień nazwę pliku tymczasowego z powrotem na
bar
.Ten ostatni krok przywraca zmienioną zawartość do pliku.
Chociaż może to zadziałać, jeśli przeniesiony plik ma zbyt inną zawartość niż oryginalny git, uzna, że skuteczniej jest zdecydować, że jest to nowy obiekt. Pokażę:
źródło
git mv
jest po prostu wygodą dla parygit rm
/git add
pary. Jeśli już zrobiłeś 'mv bar foo', wszystko, co musisz zrobić, to upewnić się, że dokonałeś zatwierdzeniagit add foo
igit rm bar
przed nim. Można to zrobić tak samo, jak pojedynczegit add -A
polecenie lubgit add foo; git commit -a
sekwencję.add
ponownym utworzeniu pliku git przerywa przenoszenie / modyfikację do usuniętego / dodanego ponownie.git commit
krok 3, w przeciwnym razie będzie niepoprawny. Ponadto @CharlesBailey ma rację, możesz równie łatwo wykonać normalnąmv blah foo
czynność w kroku 3, a następnie zatwierdzić i uzyskać te same wyniki.Jeśli mówisz o
git status
nie pokazywaniu nazw, spróbujgit commit --dry-run -a
zamiast tegoźródło
Jeśli używasz TortoiseGit, ważne jest, aby pamiętać, że automatyczne wykrywanie zmiany nazwy Gita ma miejsce podczas zatwierdzania, ale fakt, że tak się stanie, nie zawsze jest wcześniej wyświetlany przez oprogramowanie. Przeniosłem dwa pliki do innego katalogu i dokonałem niewielkich zmian. Używam TortoiseGit jako mojego narzędzia do zatwierdzania, a lista wprowadzonych zmian pokazała, że pliki są usuwane i dodawane, a nie przenoszone. Uruchomienie statusu git z wiersza poleceń pokazało podobną sytuację. Jednak po zatwierdzeniu plików pojawiły się w dzienniku jako przemianowane. Tak więc odpowiedź na twoje pytanie jest taka, o ile nie zrobiłeś nic zbyt drastycznego, Git powinien automatycznie zmienić nazwę.
Edycja: Najwyraźniej jeśli dodasz nowe pliki, a następnie wykonasz status git z wiersza poleceń, zmiana nazwy powinna pojawić się przed zatwierdzeniem.
Edycja 2: Ponadto, w TortoiseGit, dodaj nowe pliki w oknie dialogowym zatwierdzenia, ale ich nie zatwierdzaj. Następnie, jeśli przejdziesz do polecenia Pokaż dziennik i spojrzysz na katalog roboczy, zobaczysz, czy Git wykrył zmianę nazwy przed zatwierdzeniem.
To samo pytanie zostało zadane tutaj: https://tortoisegit.org/issue/1389 i zostało zarejestrowane jako błąd do naprawy tutaj: https://tortoisegit.org/issue/1440 Okazuje się, że jest to problem z wyświetlaniem w zatwierdzeniu TortoiseGit dialog, a także istnieje w stanie git, jeśli nie dodałeś nowych plików.
źródło
Albo możesz spróbować odpowiedzieć na to pytanie tutaj przez Amber ! Cytując to jeszcze raz:
Najpierw anuluj dodawanie etapowe dla ręcznie przeniesionego pliku:
Następnie użyj Git, aby przenieść plik:
Oczywiście, jeśli już dokonałeś ręcznego przenoszenia, możesz zamiast tego zresetować wersję przed przeniesieniem, a następnie po prostu pobrać stamtąd mv.
źródło
Użyj
git mv
polecenia, aby przenieść pliki, zamiast poleceń przenoszenia systemu operacyjnego: https://git-scm.com/docs/git-mvPamiętaj, że
git mv
polecenie istnieje tylko w Git w wersji 1.8.5 i nowszych. Może być konieczne zaktualizowanie Gita, aby użyć tego polecenia.źródło
Ostatnio miałem ten problem podczas przenoszenia (ale nie modyfikowania) niektórych plików.
Problem polega na tym, że Git zmienił niektóre zakończenia linii, gdy przenosiłem pliki, a następnie nie był w stanie stwierdzić, że pliki były takie same.
Korzystanie
git mv
z rozwiązania problemu, ale działa tylko na pojedyncze pliki / katalogi, a ja miałem wiele plików w katalogu głównym repozytorium do zrobienia.Jednym ze sposobów naprawienia tego byłoby użycie magii typu bash / batch.
Inny sposób jest następujący
git commit
. To aktualizuje zakończenia linii.git commit --amend
git commit --amend
. Tym razem nie ma zmian w zakończeniach linii, więc Git jest szczęśliwyźródło
Dla mnie zadziałało przechowywanie wszystkich zmian przed zatwierdzeniem i wyskakiwanie ich ponownie. To spowodowało, że git ponownie przeanalizował dodane / usunięte pliki i poprawnie oznaczył je jako przeniesione.
źródło
Jest na to prawdopodobnie lepszy sposób „wiersza poleceń” i wiem, że to hack, ale nigdy nie byłem w stanie znaleźć dobrego rozwiązania.
Korzystanie z TortoiseGIT: Jeśli masz zatwierdzenie GIT, w którym niektóre operacje przenoszenia plików są wyświetlane jako ładunek dodawania / usuwania zamiast zmiany nazw, nawet jeśli pliki mają tylko niewielkie zmiany, wykonaj następujące czynności:
Nowe zatwierdzenie będzie teraz poprawnie wyświetlało nazwy plików… co pomoże utrzymać właściwą historię plików.
źródło
Kiedy jednocześnie edytuję, zmieniam nazwę i przenoszę plik, żadne z tych rozwiązań nie działa. Rozwiązaniem jest zrobienie tego w dwóch zatwierdzeniach (edycja i zmiana nazwy / przeniesienie osobno), a następnie
fixup
w drugim zatwierdzeniu za pomocągit rebase -i
jednego zatwierdzenia.źródło
Rozumiem to pytanie: „Jak sprawić, aby git rozpoznał usunięcie starego pliku i utworzenie nowego pliku jako przeniesienie pliku”.
Tak w katalogu roboczym po usunięciu starego pliku i wstawieniu starego pliku,
git status
powie „deleted: old_file
” i „Untracked files: ... new_file
”Ale w indeksie pomostowym / poziomie po dodaniu i usunięciu pliku za pomocą git zostanie rozpoznany jako przeniesienie pliku. Aby to zrobić, zakładając, że wykonałeś usuwanie i tworzenie za pomocą swojego systemu operacyjnego, podaj następujące polecenia:
Jeśli zawartość pliku jest w 50% lub więcej podobna, uruchomiona
git status
komenda powinna dać ci:źródło
git status
powie „deleted: old_file
” i „Untracked files: ... new_file
”: Nie od Gita 2.18: stackoverflow.com/a/50573107/6309