2016-10-29 2 views
0

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"

+0

S'ils sont identiques, pourquoi est-ce important de savoir ce que vous avez pris? – jthill

Répondre

1

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.