remota - git tags best practices
Enumerando cada rama y la fecha de su última revisión en git (10)
Aquí hay una función que puede agregar a su perfil bash_ para facilitar esto.
Uso cuando en un repositorio git:
-
branch
imprime todas las sucursales locales -
branch -r
imprime todas las sucursales remotas
Función:
branch() {
local pattern="s/^..//"
local arg=""
if [[ $@ == "-r" ]]; then
pattern="s/^..(.*?)( ->.*)?$//1/"
arg=" -r "
echo ''-r provided''
fi
for k in $(git branch $arg | perl -pe "$pattern"); do
echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1)//t$k
done | sort -r
}
Necesito eliminar ramas antiguas y sin mantenimiento de nuestro repositorio remoto. Estoy intentando encontrar una forma de enumerar las sucursales remotas en su última fecha de modificación, y no puedo.
¿Alguien sabe de una manera fácil de enumerar sucursales remotas de esta manera?
En Powershell, muestra las sucursales en el control remoto que ya están fusionadas y tienen al menos dos semanas de antigüedad. (autor: el formato relativo comienza a mostrar semanas en lugar de días a las dos semanas)
$safeBranchRegex = "origin/(HEAD|master|develop)$";
$remoteMergedBranches = git branch --remote --merged | %{$_.trim()};
git for-each-ref --sort=''authordate:iso8601'' --format='' %(authordate:relative)%09%(refname:short)'' refs/remotes | ?{$_ -match "(weeks|months|years) ago" -and $_ -notmatch "origin/(HEAD|master|qa/)"} | %{$_.substring($_.indexof("origin/"))} | ?{$_ -in $remoteMergedBranches}
Esto es lo que se me ocurrió después de haber revisado this .
for REF in $(git for-each-ref --sort=-committerdate --format="%(objectname)" /
refs/remotes refs/heads)
do
if [ "$PREV_REF" != "$REF" ]; then
PREV_REF=$REF
git log -n1 $REF --date=short /
--pretty=format:"%C(auto)%ad %h%d %s %C(yellow)[%an]%C(reset)"
fi
done
La comprobación PREV_REF
consiste en eliminar duplicados si más de una rama apunta al mismo compromiso. (Como en la sucursal local que también existe en el control remoto).
git branch --merged
CUENTA que según la solicitud OP, git branch --merged
y git branch --no-merged
son útiles para identificar qué ramas se pueden eliminar fácilmente. [ https://git-scm.com/docs/git-branch]
Esto es lo que uso:
git for-each-ref --sort=''-committerdate:iso8601'' --format='' %(committerdate:iso8601)%09%(refname)'' refs/heads
Este es el resultado:
2014-01-22 11:43:18 +0100 refs/heads/master
2014-01-22 11:43:18 +0100 refs/heads/a
2014-01-17 12:34:01 +0100 refs/heads/b
2014-01-14 15:58:33 +0100 refs/heads/maint
2013-12-11 14:20:06 +0100 refs/heads/d/e
2013-12-09 12:48:04 +0100 refs/heads/f
Para sucursales remotas, simplemente use "refs / remotes" en lugar de "refs / heads":
git for-each-ref --sort=''-committerdate:iso8601'' --format='' %(committerdate:iso8601)%09%(refname)'' refs/remotes
Es posible que desee llamar a "git fetch --prune" antes de tener la información más reciente.
Hice dos variantes, basadas en la respuesta de VonC.
Mi primera variante
for k in `git branch -a | sed -e s/^..// -e ''s/(detached from .*)/HEAD/''`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --`;done | sort | column -t -s "|"
Esto maneja las ramas locales y remotas (-a), maneja el estado de cabeza separada (el comando sed más largo, aunque la solución es un tanto tosca; simplemente reemplaza la información de rama separada con la palabra clave HEAD), agrega en el sujeto de confirmación ( % s), y coloca cosas en columnas a través de caracteres de tubería literales en la cadena de formato y pasando el resultado final a la column -t -s "|"
. (Puede usar lo que sea como separador, siempre que sea algo que no espera en el resto de la salida).
Mi segunda variante es bastante hacky, pero realmente quería algo que todavía tenga un indicador de "esta es la rama en la que estás actualmente", como lo hace el comando de rama.
CURRENT_BRANCH=0
for k in `git branch -a | sed -e ''s//*/CURRENT_BRANCH_MARKER/'' -e ''s/(detached from .*)/HEAD/''`
do
if [ "$k" == ''CURRENT_BRANCH_MARKER'' ]; then
# Set flag, skip output
CURRENT_BRANCH=1
elif [ $CURRENT_BRANCH == 0 ]; then
echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --`
else
echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset* %Cgreen$k%Creset |%s" $k --`
CURRENT_BRANCH=0
fi
done | sort | column -t -s "|"
Esto convierte el * que marca la rama actual en una palabra clave, y cuando el cuerpo del bucle ve la palabra clave, en su lugar establece un indicador y no genera nada. El indicador se usa para indicar que se debe usar un formato alternativo para la siguiente línea. Como dije, totalmente hacky, ¡pero funciona! (En su mayoría, por alguna razón mi última columna se está superando en la línea actual, pero realmente debería volver a hacer el trabajo real en lugar de modificarlo más).
O puede usar mi script php https://gist.github.com/2780984
#!/usr/bin/env php
<?php
$local = exec("git branch | xargs $1");
$lines = explode(" ", $local);
$limit = strtotime("-2 week");
$exclude = array("*", "master");
foreach ($exclude as $i) {
$k = array_search($i, $lines);
unset($lines[$k]);
}
$k = 0;
foreach ($lines as $line) {
$output[$k][''name''] = $line;
$output[$k][''time''] = exec(''git log ''.$line.'' --pretty=format:"%at" -1'');
if ($limit>$output[$k][''time'']) {
echo "This branch should be deleted $line/n";
exec("git branch -d $line");
}
$k++;
}
Partiendo de Olivier Croquette , me gusta utilizar una fecha relativa y acortar el nombre de la rama de esta manera:
git for-each-ref --sort=''-authordate:iso8601'' --format='' %(authordate:relative)%09%(refname:short)'' refs/heads
Lo que te da salida:
21 minutes ago nathan/a_recent_branch
6 hours ago master
27 hours ago nathan/some_other_branch
29 hours ago branch_c
6 days ago branch_d
Recomiendo hacer un archivo bash para agregar todos sus alias favoritos y luego compartir el guión con su equipo. Aquí hay un ejemplo para agregar solo este:
#!/bin/sh
git config --global alias.branches "!echo '' ------------------------------------------------------------'' && git for-each-ref --sort=''-authordate:iso8601'' --format='' %(authordate:relative)%09%(refname:short)'' refs/heads && echo '' ------------------------------------------------------------''"
A continuación, puede hacer esto para obtener una lista de sucursales locales bien formateada y ordenada:
git branches
Ramas remotas ordenadas y la fecha del último compromiso para cada rama.
for branch in `git branch -r | grep -v HEAD`;do echo -e `git show --format="%ci %cr" $branch | head -n 1` //t$branch; done | sort -r
Solo para agregar al comentario de @VonC, tome su solución preferida y agréguela a su lista de alias ~ / .gitconfig para mayor comodidad:
[alias]
branchdate = !git for-each-ref --sort=''-authordate'' --format=''%(refname)%09%(authordate)'' refs/heads | sed -e ''s-refs/heads/--''
Luego, un simple "branchdate de git" imprime la lista para usted ...
commandlinefu tiene 2 proposiciones interesantes:
for k in `git branch | perl -pe s/^..//`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`//t$k; done | sort -r
o:
for k in `git branch | sed s/^..//`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k --`//t"$k";done | sort
Eso es para las sucursales locales, en una sintaxis de Unix. Usando la git branch -r
, también puede mostrar ramas remotas:
for k in `git branch -r | perl -pe ''s/^..(.*?)( ->.*)?$//1/''`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`//t$k; done | sort -r
Michael Forrest menciona en los comentarios que zsh requiere escapes para la expresión sed
:
for k in git branch | perl -pe s///^/././///; do echo -e git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1//t$k; done | sort -r
kontinuity agrega en los comentarios :
Si desea agregarlo a su zshrc, se necesita el siguiente escape.
alias gbage=''for k in `git branch -r | perl -pe ''/'''s/^..(.*?)( ->.*)?$//1/''/'''`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`//t$k; done | sort -r''
En múltiples líneas:
alias gbage=''for k in `git branch -r | /
perl -pe ''/'''s/^..(.*?)( ->.*)?$//1/''/'''`; /
do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | /
head -n 1`//t$k; done | sort -r''