comando git per spostare una cartella all'interno di un'altra


194

Ho creato una cartella commoncon un mucchio di file e cartelle di origine.

Ora voglio spostare la commoncartella nella cartella in includemodo che appaiainclude/common

Ho provato questi:

  1. git add include

  2. git mv common/ include/

    ma non riesce con questo errore

    fatale: sorgente non valida, fonte = myrepo / comune, destinazione = myrepo / include

  3. Ho provato git mv common/ include/commonma ho lo stesso errore

Qualche idea su come raggiungere questo obiettivo?

Risposte:


177

Una delle cose più belle di Git è che non è necessario tenere traccia dei nomi dei file in modo esplicito. Git lo capirà confrontando il contenuto dei file.

Quindi, nel tuo caso, non lavorare così duramente:

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

La corsa git statusdovrebbe mostrarti qualcosa del genere:

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

44
Questo non funziona per me (utilizzando Windows 7, 1.7.6.msysgit.0). Git pensa che i vecchi file siano stati eliminati e che siano stati aggiunti nuovi file.
Bart,

Hmm, forse git usa qualche utility esterna per determinare l'identità dei file che non funziona su Windows? Questa è stata una parte fondamentale dell'implementazione di git.
Andres Jaan Tack,

13
@OliverF. Correzione: git mvè equivalente.
Andres Jaan Tack,

25
"Una delle cose più belle di git" - uno degli aspetti negativi di questa bella funzionalità è che inizia a fallire quando si modifica anche il file che è stato rinominato in misura sostanziale, il che gli fa vedere una cancellazione e l'aggiunta di un nuovo file , francamente, preferirei invece il supporto per rinominare esplicitamente.
Erik Kaplun,

2
Se git converte le terminazioni di linea, questo si traduce nel problema descritto da @Bart. Perché questo funzioni devi fare quanto segue: git config --global core.autocrlf false
Mariano Dupont

164
 git mv common include

dovrebbe funzionare.

Dalla git mvpagina man :

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

Nella seconda forma, l'ultimo argomento deve essere una directory esistente; le fonti indicate verranno spostate in questa directory .
L'indice viene aggiornato dopo il completamento con esito positivo, ma è comunque necessario eseguire il commit della modifica.

Nessun " git add" dovrebbe essere fatto prima del trasloco.


Nota: " git mv A B/", quando Bnon esiste come directory, dovrebbe essere errato, ma non è stato così.

Vedi commit c57f628 di Matthieu Moy ( moy) per Git 1.9 / 2.0 (Q1 2014):

Git usava tagliare la barra finale e rendere il comando equivalente a " git mv file no-such-dir", che ha creato il file no-such-dir(mentre la barra finale ha dichiarato esplicitamente che poteva essere solo una directory).

Questa patch salta la rimozione della barra finale per il percorso di destinazione.
Il percorso con la sua barra finale viene passato a rinomina (2), che viene eliminato con il messaggio appropriato:

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

2
Ha funzionato perfettamente - e l'utilizzo git mvsembra un approccio molto migliore!
Tomas Petricek,

23

Comando:

$ git mv oldFolderName newFolderName

Di solito funziona bene.

L'errore "sorgente non valida ..." indica in genere che dopo l'ultimo commit c'erano alcuni rinominati nella directory di origine e quindi git mvnon è possibile trovare il file previsto.

La soluzione è semplice: basta impegnarsi prima di applicare git mv.


15

Assicurati di aver aggiunto tutte le modifiche all'area di gestione temporanea prima di eseguire

git mv oldFolderName newFoldername

git fallisce con errore

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

se ci sono file non aggiunti, quindi ho appena scoperto.


"se ci sono file non aggiunti, quindi ho appena scoperto." - Grazie!
cacoder

3

Un altro modo per spostare tutti i file di una directory in una sottodirectory (mantiene la cronologia di git):

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


Attenzione: se nella cartella / nel nome del file è presente uno spazio, ciò causerà problemi!
Dejoma

3

Ho avuto un problema simile con il punto in git mvcui volevo spostare il contenuto di una cartella in una cartella esistente e ho finito con questo script "semplice":

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

Spiegazione

  • git ls-files: Trova tutti i file (nella commoncartella) archiviati in git
  • newdir="../include/$(dirname $f)"; mkdir -p $newdir;: Crea una nuova cartella all'interno della includecartella, con la stessa struttura di directory dicommon
  • git mv $f $newdir/$(basename "$f"): Sposta il file nella cartella appena creata

Il motivo di ciò è che git sembra avere problemi a spostare i file in cartelle esistenti e fallirà anche se provi a spostare un file in una cartella inesistente (quindi mkdir -p).

La cosa bella di questo approccio è che tocca solo i file che sono già stati registrati su git. Semplicemente usando git mvper spostare un'intera cartella e la cartella contiene modifiche non messe in scena, git non saprà cosa fare.

Dopo aver spostato i file, potresti voler pulire il repository per rimuovere tutte le modifiche non messe in scena rimanenti - ricorda solo di eseguire prima l'esecuzione a secco!

git clean -fd -n

Attenzione: se nella cartella / nel nome del file è presente uno spazio, ciò causerà problemi!
Dejoma

2

Mi dispiace di non avere abbastanza reputazione per commentare la "risposta" di "Andres Jaan Tack".

Penso che il mio messege verrà eliminato ((ma voglio solo avvisare "Lurscher" e altri che hanno avuto lo stesso errore: state attenti a fare

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

Potrebbe non essere possibile visualizzare la cronologia git del progetto in una nuova cartella.

ci ho provato

$ git mv oldFolderName newFolderName

avuto

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

L'ho fatto

git rm -r oldFolderName

e

git add newFolderName

e non vedo la vecchia storia di git nel mio progetto. Almeno il mio progetto non è perso. Ora ho il mio progetto in newFolderName, ma senza la cronologia (

Voglio solo avvisare, fai attenzione usando i consigli di "Andres Jaan Tack", se non vuoi perdere il tuo git hsitory.


Assicurati che tutte le modifiche siano state aggiunte. Git non riesce a dire "sorgente errata" se ci sono cambiamenti non modificati, quindi l'ho appena scoperto.
Kevin Pluck,

0

Ho avuto un problema simile, ma nella cartella che volevo spostare avevo dei file che non stavo monitorando.

diciamo che avevo dei file

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

E volevo spostare solo i file tracciati nella sottocartella subdir, quindi l'obiettivo era:

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

quello che avevo fatto era:

  • Ho creato una nuova cartella e spostato tutti i file che mi interessavano spostare: mkdir tmpdir && mv a b tmpdir
  • verificato vecchi file git checkout a b
  • ha creato una nuova directory e spostato le cartelle pulite (senza file non tracciati) nel nuovo sottodir: mkdir subdir && mv a b subdir
  • ha aggiunto tutti i file da subdir (in modo che Git potesse aggiungere solo i file tracciati in precedenza - era un po 'come git add --updatecon il trucco di modifica della directory ): git add subdir(normalmente questo aggiungerebbe anche i file non tracciati - questo richiederebbe la creazione di .gitignorefile)
  • git status mostra ora solo i file spostati
  • spostato il resto dei file da tmpdir al sottodir: mv tmpdir/* subdir
  • git statussembra che abbiamo eseguito git mv:)

-1

Ho risolto questo su Windows facendo questo:

  • Apri la console Power shell
  • esegui dir
  • Alt-clic e trascinare sulla colonna del nome file / cartella, quindi copia
  • Incolla nel blocco note ++
  • esegui sostituisci con regex: sostituisci (.*)congit mv ".\\\1" ".\\<New_Folder_Here>\"
  • copia tutto il testo da Notepad ++ in PowerShell
  • premi invio
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.