2012-09-12 15 views
31

Czy można wykonać następujące czynności?Jak uruchomić reorganizację git - interaktywną w sposób nieinteraktywny?

  1. Spraw, aby git rebase --interactive wyprowadzał standardową płytę główną do pliku, zamiast tego wyprowadzał do pliku i otwierał go w edytorze.
  2. Pozwól użytkownikowi edytować plik.
  3. Pozwól użytkownikowi ponownie uruchomić git rebase z nazwą edytowanego pliku.
  4. Kontynuuj ze zwykłym procesem rebase.

Usecase: skryptowe przebijanie oczywiście. Zobacz na przykład how to re-order commits in Git non-interactively.

+0

Zobacz http://stackoverflow.com/questions/12270357/really-flatten-a-git-merge, gdzie również byłoby to przydatne. – pfalcon

+0

Oprócz git rebase poniżej, git filter-branch to kolejna opcja: http://stackoverflow.com/questions/19636750/git-filter-branch-msg-filter-to-reword-a-hedhed-commit-message – MarcH

Odpowiedz

41

Po pewnym zastanowieniu i poszukiwaniach odpowiedź okazała się banalna: git rebase -i przyjmuje nazwę edytora ze znanych zmiennych środowiskowych EDITOR/VISUAL, więc nadpisanie tego, aby wskazywać na nieinteraktywny skrypt, wykonuje to zadanie.

Jednak EDYTOR/WIZUALNY stosuje się obojętnie do listy zatwierdzeń, zatwierdzania komunikatów podczas przeredagowania i czegokolwiek innego. Tak więc od http://git.kernel.org/?p=git/git.git;a=commit;h=821881d88d3012a64a52ece9a8c2571ca00c35cd istnieje specjalna zmienna środowiskowa GIT_SEQUENCE_EDITOR, która dotyczy tylko listy commitów.

Więc przepis na ponowne zamówienie lub spłaszczyć zobowiązuje się:

Run: GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>. Twój <script> powinien zaakceptować pojedynczy argument: ścieżkę do pliku zawierającego standardową listę zatwierdzania rebase. Powinien przepisać go na miejscu i wyjść. Zwykle po tym następuje przetwarzanie bazy danych.

+0

nie znać 'GIT_SEQUENCE_EDITOR', wydaje się przydatna;) – c00kiemon5ter

+2

Lub, zamiast tworzyć skrypt dla tego wyłącznego celu, wystarczy użyć istniejącego polecenia' true', które ignoruje wszelkie argumenty i ma ustalony kod powrotu '0'. –

+3

@me_i to tylko pomaga, jeśli chcesz zrobić 'rebase -i' bez zmiany kolejności zatwierdzeń. –

2

Tryby interaktywne wywołują edytor ustawień do pracy.
redaktor użytkowania można pobrać z:

git config --get core.editor 

Więc jeśli ustawisz nieinteraktywną edytora - czyli edytor, który akceptuje polecenia na stdin, można pracować z --interactive w sposób non -interaktywny sposób :)
Wiem na pewno, że vim przyjmuje polecenia, podobnie jak standardowy edytored, ofcourse.

tak trzymaj interaktywny edytor (jeśli chciał)

$ ied="$(git config --get core.editor)" 

ustawić nieinteraktywną edytor

$ git config --unset-all core.editor 
$ git config --add core.editor ed 

i pracują z nim ..

$ printf '%s\n' "some-ed-cmd" "another-ed-cmd" "wq" | git rebase -i HEAD~5 

i przywrócić edytor (jeśli potrzebny)

$ git config --unset-all core.editor 
$ git config --add core.editor "$ied" 
+0

Dzięki, prawdopodobnie zaczęliśmy pisać odpowiedzi w podobnym czasie, nie widziałem twoich zanim napisałem moje ;-) – pfalcon

+0

Myślę, że łatwiej jest ponownie zdefiniować EDITOR, zarówno na podstawie sesji, jak i polecenia. – MarcH

+1

Zdecydowanie odradzam wykonywanie 'git config --unset-all' lub cokolwiek innego, co zmodyfikuje plik konfiguracyjny użytkownika w skrypcie. Aby ustawić zmienną konfiguracyjną git dla jednego polecenia, użyj 'git -c var = val', iw tym przypadku ustawienie' EDITOR' jest znacznie prostsze. Jest to zmienna środowiskowa, więc dotyczy tylko bieżącego procesu, nie będzie zakłócać innych procesów ani zapisywać czegokolwiek na dysku. –

4

Dodając do odpowiedzi @ pfalcon, możesz użyć sed jako GIT_SEQUENCE_EDITOR.Na przykład, chciałem edytować każdy popełnić, więc zrobiłem to:

GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i 
4

używam tego skryptu (na dodatek pozwala uprościć popełnić dzielenie):

#!/bin/bash 

ACTION=$1 
COMMIT=$(git rev-parse --short $2) 
[[ "$COMMIT" ]] || exit 1 
CORRECT= 
for A in p pick r reword e edit s squash f fixup x exec d delete t split; do 
    [[ $ACTION == $A ]] && CORRECT=1 
done 
[[ "$CORRECT" ]] || exit 1 
if [[ $ACTION == "delete" || $ACTION == "d" ]]; then 
    GIT_SEQUENCE_EDITOR="sed -i -e '/^pick $COMMIT/d'" git rebase -i $COMMIT^^ 
elif [[ $ACTION == "split" || $ACTION == "t" ]]; then 
    GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/edit $COMMIT/'" git rebase -i $COMMIT^^ || exit 1 
    git reset --soft HEAD^ 
    echo "Hints:" 
    echo " Select files to be commited using 'git reset', 'git add' or 'git add -p'" 
    echo " Commit using 'git commit -c $COMMIT'" 
    echo " Finish with 'git rebase --continue'" 
else 
    GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/$1 $COMMIT/'" git rebase -i $COMMIT^^ 
fi 

Dodaj alias do swojego. gitconfig:

[alias] 
    autorebase = ! path_to_your_script 
5

Rozszerzając pfalcon za odpowiedź:

Uruchom GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>. <script> powinien akceptować pojedynczy argument - ścieżkę do pliku zawierającego standardową listę zatwierdzania rebase. Skrypt powinien przepisać go na miejscu i wyjść. Zwykle po tym następuje przetwarzanie bazy danych.

Jeśli masz zmienną środowiskową, która zawiera zawartość chcesz:

GIT_SEQUENCE_EDITOR='echo "$REBASE_DATA" >' git rebase -i [<additional params>] 

Catting plik będzie działać zbyt:

GIT_SEQUENCE_EDITOR='cat rebase_data_file >' git rebase -i [<additional params>] 
2

Można użyć touch jako redaktor, który poruszy plik, aby wyglądał na zmodyfikowany. Na przykład

GIT_SEQUENCE_EDITOR=touch git rebase -i [commit] 

Aby aliasu go, biorąc pod uwagę baseline jako znacznik chcę zmieniają bazę przed

git config alias.baseline '!GIT_SEQUENCE_EDITOR=touch git rebase -i baseline' 

Alias ​​pracuje pod kontrolą systemu Windows, ponieważ powłoka jest wykonywany jest bash nie cmd.

+0

Działa to dobrze z 'git --interactive --exec '. Ustawiam '' na polecenie, które uruchamia testy wprowadzone lub zmodyfikowane przez moją gałąź, oraz '' na 'master'. To powoduje, że git uruchamia moje testy dla każdego zatwierdzenia w oddziale. – Mike

0

podstawie Jezz's answer, Zrobiłem shell-agnostyk skrypt (GitReb) który współpracuje z wieloma wersjami argument :/<text> składnia, korzeń popełnienia, a także wykonuje kilka testów poprawności.

Ja również prostsze i usunął t/split działania i delete ->drop konwersję które IMO są poza zakresem tego skryptu.