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ąć?

lurscher
źródło

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
#
Andres Jaan Tack
źródło
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
VonC
źródło
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.

Igor Zvorygin
źródło
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.

Kevin Pluck
źródło
„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;

Michał Smoleński
źródło
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
loket
źródło
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.

Ivan F.
źródło
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:)
test30
źródło
-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
FalcoGer
źródło