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 y3830e61
es malo. Cuando ejecuto un git bisect, se cometen107ca95..3e667f8
se ignoran. Sé que43a07b1
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