polecenie git, aby przenieść folder do innego


193

Utworzyłem folder commonz wieloma plikami źródłowymi i folderami.

Teraz chcę przenieść commonfolder do includefolderu, aby wyglądałinclude/common

Próbowałem tych:

  1. git add include

  2. git mv common/ include/

    ale zawodzi z tym błędem

    fatal: złe źródło, source = myrepo / common, destination = myrepo / include

  3. Próbowałem, git mv common/ include/commonale pojawia się ten sam błąd

Masz pomysł, jak to osiągnąć?

Odpowiedzi:


177

Jedną z najpiękniejszych rzeczy w git jest to, że nie trzeba jawnie śledzić zmian nazw plików. Git odkryje to, porównując zawartość plików.

Więc w twoim przypadku nie pracuj tak ciężko:

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

Bieganie git statuspowinno pokazać coś takiego:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    common/file.txt -> include/common/file.txt
#

43
To nie działa dla mnie (w systemie Windows 7, 1.7.6.msysgit.0). Git uważa, że ​​stare pliki zostały usunięte i dodano nowe.
— Bart

Hmm, może git używa jakiegoś zewnętrznego narzędzia do określenia identyczności plików, czy taht nie działa w systemie Windows? To był podstawowy element implementacji gita.
— Andres Jaan Tack

13
@OliverF. Korekta: git mvjest równoważna.
— Andres Jaan Tack,

25
„Jedną z najpiękniejszych rzeczy w git” - jedną z wad tej miłej funkcji jest to, że zaczyna się ona zawodzić, gdy modyfikujesz również plik, którego nazwę zmieniono w znacznym stopniu, co powoduje, że widzi usunięcie i dodanie nowego pliku , więc szczerze mówiąc wolałbym zamiast tego jawnie zmienić nazwę.
— Erik Kaplun

2
Jeśli git konwertuje zakończenia linii, powoduje to problem opisany przez @Bart. Aby to zadziałało, musisz wykonać następujące czynności: git config --global core.autocrlf false
— Mariano Dupont

163
 git mv common include

powinno działać.

Od git mvstrony man :

git mv [-f] [-n] [-k] <source> ... <destination directory>

W drugiej formie ostatnim argumentem musi być istniejący katalog; podane źródła zostaną przeniesione do tego katalogu .
Indeks jest aktualizowany po pomyślnym zakończeniu, ale zmiana musi zostać zatwierdzona.

Przed przeniesieniem git addnie należy wykonywać żadnych czynności „ ” .


Uwaga: „ git mv A B/”, gdy Bnie istnieje jako katalog, powinno zostać błędnie wykonane, ale tak się nie stało.

Zobacz zatwierdzenie c57f628 przez Matthieu Moy ( moy) dla Git 1.9 / 2.0 (Q1 2014):

Git przycinał końcowy ukośnik i uczynił polecenie równoważnym „ git mv file no-such-dir”, który utworzył plik no-such-dir(podczas gdy ukośnik wyraźnie stwierdził, że może to być tylko katalog).

Ta łatka pomija usuwanie ukośnika końcowego dla ścieżki docelowej.
Ścieżka z końcowym ukośnikiem jest przekazywana do zmiany nazwy (2), co powoduje błąd przy odpowiednim komunikacie:

$ git mv file no-such-dir/
fatal: renaming 'file' failed: Not a directory

2
Działa idealnie - a używanie git mvwygląda na znacznie lepsze podejście!
— Tomas Petricek

23

Komenda:

$ git mv oldFolderName newFolderName

Zwykle działa dobrze.

Błąd „złe źródło ...” zwykle wskazuje, że po ostatnim zatwierdzeniu w katalogu źródłowym były pewne nazwy i dlatego git mvnie można znaleźć oczekiwanego pliku.

Rozwiązanie jest proste - wystarczy zatwierdzić przed złożeniem wniosku git mv.


15

Przed uruchomieniem upewnij się, że wszystkie zmiany zostały dodane do obszaru pomostowego

git mv oldFolderName newFoldername

git kończy się niepowodzeniem z błędem

fatal: bad source, source=oldFolderName/somepath/somefile.foo, destination=newFolderName/somepath/somefile.foo

jeśli są jakieś nieaddowane pliki, więc właśnie się dowiedziałem.


„jeśli są jakieś nieaddowane pliki, to właśnie się dowiedziałem”. - dzięki!
— kakoder

3

Inny sposób przeniesienia wszystkich plików z katalogu do podkatalogu (zachowuje historię git):

$ for file in $(ls | grep -v 'subDir'); do git mv $file subDir; done;


Ostrożnie: jeśli w nazwie folderu / pliku jest miejsce, spowoduje to problemy!
— dejoma

3

Miałem podobny problem z tym, git mvgdzie chciałem przenieść zawartość jednego folderu do istniejącego folderu i skończyłem na tym „prostym” skrypcie:

pushd common; for f in $(git ls-files); do newdir="../include/$(dirname $f)"; mkdir -p $newdir; git mv $f $newdir/$(basename "$f"); done; popd

Wyjaśnienie

  • git ls-files: Znajdź wszystkie pliki (w commonfolderze) zarejestrowane w git
  • newdir="../include/$(dirname $f)"; mkdir -p $newdir;: Utwórz nowy folder w includefolderze o takiej samej strukturze katalogów jakcommon
  • git mv $f $newdir/$(basename "$f"): Przenieś plik do nowo utworzonego folderu

Powodem tego jest to, że git wydaje się mieć problemy z przenoszeniem plików do istniejących folderów, a także zawiedzie, jeśli spróbujesz przenieść plik do nieistniejącego folderu (stąd mkdir -p).

Zaletą tego podejścia jest to, że dotyka on tylko plików, które są już zarejestrowane w git. Po prostu używając git mvdo przeniesienia całego folderu, który zawiera nieustawione zmiany, git nie będzie wiedział, co zrobić.

Po przeniesieniu plików możesz wyczyścić repozytorium, aby usunąć wszelkie pozostałe niestabilne zmiany - pamiętaj tylko, aby najpierw uruchomić na sucho!

git clean -fd -n

Ostrożnie: jeśli w nazwie folderu / pliku jest miejsce, spowoduje to problemy!
— dejoma

2

Przepraszam, że nie mam wystarczającej reputacji, aby skomentować „odpowiedź” „Andres Jaan Tack”.

Myślę, że moja wiadomość zostanie usunięta ((ale chcę tylko ostrzec „lurschera” i innych, którzy dostali ten sam błąd: bądź ostrożny, robiąc

$ mkdir include
$ mv common include
$ git rm -r common
$ git add include/common

Może to spowodować, że nie zobaczysz historii git swojego projektu w nowym folderze.

próbowałem

$ git mv oldFolderName newFolderName

dostał

fatal: bad source, source=oldFolderName/somepath/__init__.py, dest
ination=ESWProj_Base/ESWProj_DebugControlsMenu/somepath/__init__.py

Zrobiłem

git rm -r oldFolderName

i

git add newFolderName

i nie widzę starej historii gitów w moim projekcie. Przynajmniej mój projekt nie jest stracony. Teraz mam swój projekt w newFolderName, ale bez historii (

Po prostu chcę ostrzec, bądź ostrożny, korzystając z rad „Andres Jaan Tack”, jeśli nie chcesz stracić swojego gitarzysty.


Upewnij się, że wszystkie zmiany zostały dodane. Git nie powie „złe źródło”, jeśli są niedopasowane zmiany, więc właśnie się dowiedziałem.
— Kevin Pluck,

0

Miałem podobny problem, ale w folderze, który chciałem przenieść, miałem pliki, których nie śledziłem.

powiedzmy, że miałem pliki

a/file1
a/untracked1
b/file2
b/untracked2

Chciałem przenieść tylko śledzone pliki do podfolderu subdir , więc celem było:

subdir/a/file1
subdir/a/untracked1
subdir/b/file2
subdir/b/untracked2

co zrobiłem to:

  • Utworzyłem nowy folder i przeniosłem wszystkie pliki, które chciałem przenieść: mkdir tmpdir && mv a b tmpdir
  • sprawdziłem stare pliki git checkout a b
  • utworzył nowy katalog i przeniósł czyste foldery (bez nieśledzonych plików) do nowego podkatalogu: mkdir subdir && mv a b subdir
  • dodał wszystkie pliki z podkatalogu (aby Git mógł dodawać tylko wcześniej wyśledzone pliki - to był pewien rodzaj sztuczki polegającej na git add --updatezmianie katalogu ): (normalnie dodawałoby to nawet nieśledzone pliki - wymagałoby to utworzeniagit add subdir.gitignore pliku)
  • git status pokazuje teraz tylko przeniesione pliki
  • przeniesiono resztę plików z tmpdir do podkatalogu: mv tmpdir/* subdir
  • git statuswygląda na to, że wykonaliśmy git mv:)

-1

Rozwiązałem to w systemie Windows, wykonując następujące czynności:

  • Otwórz konsolę Power shell
  • reż
  • Naciśnij i przytrzymaj klawisz Alt, a następnie przeciągnij kolumnę z nazwą pliku / folderu, a następnie skopiuj
  • Wklej do notatnika ++
  • uruchom zamień na regex: replace (.*) zgit mv ".\\\1" ".\\<New_Folder_Here>\"
  • skopiuj cały tekst z notatnika ++ do programu PowerShell
  • wciśnij Enter
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.