your you track the helps git git-bisect

you - git-blame



Git bisect con commit fusionados (3)

Esta es una pregunta muy vieja pero sin respuesta. Decidí investigar y descubrí que podía demostrar que el comportamiento de Git es diferente de lo que dice la pregunta. Una explicación es que Git mejoró el algoritmo para bisección , o que el interlocutor cometió un error al marcar commits.

Estoy tratando de aprender más y hacer bisección, pero estoy teniendo problemas con esta historia. Sé que 107ca95 es bueno y 3830e61 es malo. Cuando ejecuto un git bisect, se cometen 107ca95..3e667f8 se ignoran. Sé que 43a07b1 es el compromiso que introdujo una regresión, pero nunca se evalúa .

Escribí un código para verificar si se evalúa o no. Mi prueba muestra que es evaluada. Ejecute el siguiente código y verifique que se haya confirmado con el mensaje Add menu styles. aparece.

Más comentarios:

  • "commits 107ca95..3e667f8 se ignoran": tenga en cuenta que la confirmación que marcó como "buena" no se evaluará porque git ya sabe que es buena.
  • Lea la sección "Algoritmo de bisección" en este artículo de Christian Couder . También la sección "Comprobar bases de combinación" podría ser relevante.
  • Como se mencionó anteriormente, la pregunta fue ciertamente usando una versión diferente a la que yo usé (la pregunta es de 2013, Git 2.11 es de 2016).

Salida de ejecución Bisect

  • Observe que primero se marca ''Agregar aviso de administrador'' (línea 4) porque proporciona la mayor cantidad de información. (Lea "Verificación de las bases de combinación" del artículo mencionado anteriormente).
  • A partir de ese momento, divide la historia lineal como se esperaría.

# bad: [d7761d6f146eaca1d886f793ced4315539326866] Add data escaping. (Bad) # good: [f555d9063a25a20a6ec7c3b0c0504ffe0a997e98] Add Responsive Nav. (Good) git bisect start ''d7761d6f146eaca1d886f793ced4315539326866'' ''f555d9063a25a20a6ec7c3b0c0504ffe0a997e98'' # good: [1b3b7f4952732fec0c68a37d5f313d6f4219e4ae] Add ‘Admin’ notice. (Good) git bisect good 1b3b7f4952732fec0c68a37d5f313d6f4219e4ae # bad: [f9a65fe9e6cde4358e5b8ef7569332abfb07675e] Add icons. (Bad) git bisect bad f9a65fe9e6cde4358e5b8ef7569332abfb07675e # bad: [165b8a6e5137c40ce8b90911e59d7ec8eec30f46] Add menu styles. (Bad) git bisect bad 165b8a6e5137c40ce8b90911e59d7ec8eec30f46 # first bad commit: [165b8a6e5137c40ce8b90911e59d7ec8eec30f46] Add menu styles. (Bad)

Código

Ejecutar en Python 3 , con Git 2.11.0. Comando para ejecutar: python3 script.py

""" The following code creates a git repository in ''/tmp/git-repo'' and populates it with the following commit graph. Each commit has a test.sh which can be used as input to a git-bisect-run. The code then tries to find the breaking change automatically. And prints out the git bisect log. Written in response to http://stackoverflow.com/questions/17267816/git-bisect-with-merged-commits to test the claim that ''107ca95..3e667f8 are never checked out''. Needs Python 3! """ from itertools import chain import os.path import os import sh repo = { 0x3830e61: {''message'': "Add data escaping.", ''parents'': [ 0x0f5e148 ], ''test'': False} , # Last: (Bad) 0x0f5e148: {''message'': "Improve function for getting page template.", ''parents'': [ 0xaaf8dc5], ''test'': False}, 0xaaf8dc5: {''message'': "Merge branch ''navigation''", ''parents'': [ 0x3e667f8, 0xea3d736], ''test'': False}, 0x3e667f8: {''message'': "Add icons.", ''parents'': [ 0x43a07b1], ''test'': False}, 0x43a07b1: {''message'': "Add menu styles.", ''parents'': [ 0x107ca95], ''test'': False} , # First: (Breaks) 0x107ca95: {''message'': "Add Responsive Nav.", ''parents'': [ 0xf52cc34], ''test'': True}, # First: (Good) 0xea3d736: {''message'': "Add ‘Admin’ notice.", ''parents'': [ 0x17ca0bb], ''test'': True}, 0x17ca0bb: {''message'': "Update placeholder text.", ''parents'': [ 0xf52cc34], ''test'': True}, 0xf52cc34: {''message'': "Add featured image.", ''parents'': [ 0x2abd954], ''test'': True}, 0x2abd954: {''message'': "Style placeholders.", ''parents'': [], ''test'': True}, } bad = 0x3830e61 good = 0x107ca95 def generate_queue(_dag, parents): for prev in parents: yield prev yield from generate_queue(_dag, _dag[prev][''parents'']) def make_queue(_dag, inits): """ Converts repo (a DAG) into a queue """ q = list(generate_queue(_dag, inits)) q.reverse() seen = set() r = [x for x in q if not (x in seen or seen.add(x))] return r if __name__ == ''__main__'': pwd = ''/tmp/git-repo'' sh.rm(''-r'', pwd) sh.mkdir(''-p'', pwd) g = sh.git.bake(_cwd=pwd) g.init() parents = set(chain.from_iterable((repo[c][''parents''] for c in repo))) commits = set(repo) inits = list(commits - parents) queue = make_queue(repo, inits) assert len(queue) == len(repo), "queue {} vs repo {}".format(len(queue), len(repo)) commit_ids = {} # Create commits for c in queue: # Set up repo parents = repo[c][''parents''] if len(parents) > 0: g.checkout(commit_ids[parents[0]]) if len(parents) > 1: if len(parents) > 2: raise NotImplementedError(''Octopus merges not support yet.'') g.merge(''--no-commit'', ''-s'', ''ours'', commit_ids[parents[1]]) # just force to use ''ours'' strategy. # Make changes with open(os.path.join(pwd, ''test.sh''), ''w'') as f: f.write(''exit {:d}/n''.format(0 if repo[c][''test''] else 1)) os.chmod(os.path.join(pwd, ''test.sh''), 0o0755) with open(os.path.join(pwd, ''message''), ''w'') as f: f.write(repo[c][''message'']) g.add(''test.sh'', ''message'') g.commit(''-m'', ''{msg} ({test})''.format(msg=repo[c][''message''], test=''Good'' if repo[c][''test''] else ''Bad'')) commit_ids[c] = g(''rev-parse'', ''HEAD'').strip() # Run git-bisect g.bisect(''start'', commit_ids[bad], commit_ids[good]) g.bisect(''run'', ''./test.sh'') print(g.bisect(''log''))

Tengo un historial que se ve así:

* 3830e61 Add data escaping. (Bad) * 0f5e148 Improve function for getting page template. * aaf8dc5 Merge branch ''navigation'' |/ | * 3e667f8 Add icons. | * 43a07b1 Add menu styles. (Breaks) | * 107ca95 Add Responsive Nav. (Good) * | ea3d736 Add ‘Admin’ notice. * | 17ca0bb Update placeholder text. |/ * f52cc34 Add featured image. * 2abd954 Style placeholders.

Estoy tratando de aprender más y hacer git bisect , pero estoy teniendo problemas con esta historia. Sé que 107ca95 es bueno y 3830e61 es malo. Cuando ejecuto un git bisect , se cometen 107ca95..3e667f8 se ignoran. Sé que 43a07b1 es el compromiso que introdujo una regresión, pero nunca se evalúa.

Aquí está más o menos lo que hice:

git checkout master git bisect start git bisect bad git bisect good 107ca95 git bisect bad (multiple times)

No importa lo que haga, 107ca95..3e667f8 nunca se comprueban para probarse.

¿Hay alguna forma en la que pueda "aplanar" el historial durante la bisección para probar esos commits? Sé que puedo usar una base de datos interactiva para aplanar el historial, pero no quiero tener que hacer eso.


Esto ya está respondido

Idea básica: para encontrar qué compromiso de la rama de características rompe su maestro, tendrá que volver a aplicarlo encima de ea3d736: HEAD principal relevante.

A continuación se muestra un ejemplo (de git doc ) del script de prueba que hace eso por usted:

$ cat ~/test.sh #!/bin/sh # tweak the working tree by merging the hot-fix branch # and then attempt a build if git merge --no-commit ea3d736 && make then # run project specific test and report its status ~/check_test_case.sh status=$? else # tell the caller this is untestable status=125 fi # undo the tweak to allow clean flipping to the next commit git reset --hard # return control exit $status

Ejecutarlo:

git bisect start 3830e61 f52cc34 git bisect good ea3d736 17ca0bb #If you want to test feature branch only git bisect run ~/test.sh


Puede seleccionar el rango de commits con el comando "git start". La sinopsis del comando es:

git bisect start <bad> <good>

En su caso específico, creo que el comando correcto sería:

git bisect start 3830e61 107ca95