Je suis en train d'effectuer un rebasage et de rencontrer des conflits "les deux ajoutés" pour les fichiers binaires. Je veux accepter les nôtres si les fichiers binaires sont les mêmes, les leurs s'ils sont changés. Pendant la résolution, comment puis-je tester si les fichiers binaires sont identiques ou différents?Détermine si le fichier binaire a été modifié lors de la résolution du conflit git "les deux ajoutés"
Répondre
Vous n'obtiendrez pas un conflit si les fichiers correspondent.
Montrons ceci par l'exemple. Bien que vous parlez rebasage (vs fusion), les conflits sont traités de la même manière, car il est le même code impliqué:
$ mkdir addadd; cd addadd; git init
Initialized empty Git repository in /home/torek/tmp/addadd/.git/
$ echo a repository for testing add/add conflict > README
$ git add README
$ git commit -m initial
[master (root-commit) f665e86] initial
1 file changed, 1 insertion(+)
create mode 100644 README
Maintenant, nous avons besoin des fichiers binaires. Je vais utiliser /bin/ls
et /bin/cat
, et mettre les binaires identiques sous un nom en deux branches, et les versions non identiques sous un nom en deux branches plus:
$ git checkout -b b1 master
Switched to a new branch 'b1'
$ cp /bin/ls some-file
$ git add some-file && git commit -m 'add some-file on b1'
[b1 5128ae4] add some-file on b1
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100755 some-file
$ git checkout -b b2 master
Switched to a new branch 'b2'
$ cp /bin/ls some-file
$ git add some-file && git commit -m 'add some-file on b2'
[b2 0e7d771] add some-file on b2
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100755 some-file
Maintenant, nous essayons de fusionner b1
en b2
ou vice versa. Nous sommes déjà sur b2
donc nous allons fusionner b1
ici:
$ git merge --no-edit b1
Merge made by the 'recursive' strategy.
$ git log --oneline --decorate --graph --all
* 257e77a (HEAD -> b2) Merge branch 'b1' into b2
|\
| * 5128ae4 (b1) add some-file on b1
* | 0e7d771 add some-file on b2
|/
* f665e86 (master) initial
Maintenant, nous allons essayer la même chose avec les binaires différents:
$ git checkout -b b3 master
Switched to a new branch 'b3'
$ cp /bin/ls some-file
$ git add some-file && git commit -m 'add some-file on b3'
[b3 2ede434] add some-file on b3
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100755 some-file
$ git checkout -b b4 master
Switched to a new branch 'b4'
$ cp /bin/cat some-file
$ git add some-file && git commit -m 'add different some-file on b4'
[b4 9e5f2cf] add different some-file on b4
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100755 some-file
Encore une fois, nous allons fusionnons b3
en b4
ici:
$ git merge --no-edit b3
warning: Cannot merge binary files: some-file (HEAD vs. b3)
Auto-merging some-file
CONFLICT (add/add): Merge conflict in some-file
Automatic merge failed; fix conflicts and then commit the result.
$ git status --short
AA some-file
Cette fois, la fusion a échoué avec un conflit d'ajout/ajout. Cela signifie que les fichiers étaient différents: la fusion précédente a réussi parce que les fichiers étaient les mêmes. La fusion n'est pas complète, mais nous pouvons toujours regarder au commettras graphique:
$ git log --oneline --decorate --graph --all
* 9e5f2cf (HEAD -> b4) add different some-file on b4
| * 2ede434 (b3) add some-file on b3
|/
| * 257e77a (b2) Merge branch 'b1' into b2
| |\
| | * 5128ae4 (b1) add some-file on b1
| |/
|/|
| * 0e7d771 add some-file on b2
|/
* f665e86 (master) initial
Fait intéressant, lorsque les fichiers sont les mêmes, nous ne recevons même pas le message d'avertissement. C'est parce que les machines de fusion de Git contournent tout le code de fusion habituel quand les fichiers correspondent. En particulier, les pilotes de fusion personnalisés à partir de fichiers .gitattributes
ne sont jamais exécutés.
Nous pouvons voir les fichiers sont différents (et qu'il y avait un ajout/ajouter des conflits) en exécutant git ls-files --stage
:
$ git ls-files --stage
100644 661d9d91972de27e4f787e3ad93ea3b7a1741ddf 0 README
100755 b75a044e06fb5e093a547c4ef9a388313d27f79a 2 some-file
100755 2ca93e76b4dedc9970cca9a708ab1cb94ca032ee 3 some-file
Pathname some-file
existe comme des étapes 2 et 3, mais pas l'étape 1 (base) . Cela signifie qu'il n'y avait pas de version de base du fichier: il s'agit donc d'un conflit add/add. La valeur de hachage pour l'étape 2, --ours
, est b75a044...
, et la valeur de hachage pour l'étape 3 ou --theirs
est 2ca93e7...
, que l'on peut également voir avec git rev-parse
:
$ git rev-parse :2:some-file
b75a044e06fb5e093a547c4ef9a388313d27f79a
(pour répéter :3:some-file
si désiré).
Plus précisément, Git vérifie simplement si le hachage de l'entrée d'index correspond au hachage dans l'autre ou --theirs
commettre. Si c'est le cas, il s'agit par définition du même fichier et aucune action de fusion n'est requise.
S'ils sont identiques, pourquoi est-ce important de savoir ce que vous avez pris? – jthill