Trovo che lavorando con i sottomoduli git, mi capita spesso di incontrare problemi di fusione tra commit che contengono un dato sottomodulo e quelli che rappresentano lo stesso codice di una normale directory. Piccolo esempio riproduzione:Fusione dopo che la directory è stata trasformata in sottomodulo
# Create one project, to be used as a subproject later on
git init a
cd a
echo aaa > aa
git add -A
git commit -m a1
cd ..
# Create a second project, containing a as a normal directory initially
git init b
cd b
mkdir a b
echo aaa > a/aa
echo bbb > b/bb
git add -A
git commit -m b1
# Replace directory with submodule
git rm -r a
git submodule add ../a a
git commit -m b2
# Try to create branch from the pre-submodule state of affairs
git checkout -b branch HEAD^
Questo dà già un errore:
error: The following untracked working tree files would be overwritten by checkout:
a/aa
Please move or remove them before you can switch branches.
Aborting
Al fine di evitare l'errore, ho deinitialize tutti i sottomoduli primi:
# Create feature brach starting at version without submodule
git submodule deinit .
git checkout -b branch HEAD^
echo abc > b/bb
git commit -a -m b3
Come si può vedere, la il ramo di funzione non è completamente correlato al sottomodulo, modificando un diverso set di file. Ciò rende particolarmente fastidioso tutto questo problema.
# Try to merge the feature branch
git checkout master
git merge branch
Questo non riesce ancora una volta, con un messaggio di errore non comprendere appieno:
CONFLICT (file/directory): There is a directory with name a in branch. Adding a as a~HEAD
Automatic merge failed; fix conflicts and then commit the result.
ottengo lo stesso errore se faccio un git submodule update --init
prima della git merge branch
. Non vedo alcun a~HEAD
da nessuna parte, né nel mio albero di directory né in uscita dal git status
, che recita così:
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Changes to be committed:
modified: b/bb
Unmerged paths:
(use "git add <file>..." to mark resolution)
added by us: a
Se faccio git add a
come suggerito, ottengo un altro errore:
error: unable to index file a
fatal: updating files failed
Se faccio git submodules update --init
appena prima dell'unione, allora posso fare con successo git add a
. Ma se ho dimenticato di farlo, e quindi provare a farlo dopo l'unione, ricevo questo messaggio di errore:
Submodule 'a' (…/a) registered for path 'a'
Skipping unmerged submodule a
Come faccio a uscire da questa situazione? Qualcosa di diverso da git merge --abort
, dal momento che mi piacerebbe usarlo per cose come git rebase
pure, e dato che in alcuni scenari (non so come riprodurre) non ho potuto nemmeno interrompere l'unione in modo pulito, e ho dovuto fare un hard reset invece.
Come posso evitarlo in primo luogo? C'è qualche impostazione magica che rende git fare la cosa giusta con i sottomodati e le directory durante le unioni, così che non devo manualmente post-processare una fusione che modifica solo i file non correlati ai sottomoduli?
FYI il flag '--abort' funziona anche per rebase. – approxiblue
@ user880772: Sì, ma abortisce l'intero rebase, il che significa che uno sforzo considerevole potrebbe andare perso se ci fossero dei conflitti lungo il percorso. – MvG
Git [non gestisce la fusione del submodulo] (https://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/). Non nel suo solito modo magico. Se non vuoi dimenticare di eseguire l'aggiornamento del sottomodulo prima di un'unione, puoi trasformare "unisci" in un alias (mi sento orribile a suggerirlo). Non vedo un modo pulito intorno a questo. – approxiblue