Jak skonfigurować git push, aby automatycznie ustawiał upstream bez -u?

105

Chcę git push originautomatycznie ustawić odniesienie nadrzędne, gdy po raz pierwszy wypycham gałąź utworzoną lokalnie.

Wiem o tym git push -u, ale nie chcę myśleć o tym, czy użyłem -uwcześniej lub w inny sposób ustawiłem odniesienie nadrzędne. Innymi słowy, chcę git pushautomatycznie mieć wpływ git push -una każde wypchnięcie gałęzi, która nie ma jeszcze upstream.

czy to możliwe? Jeśli wymaga aliasu lub skryptu narzędziowego, w porządku.

Jan
źródło
2
Czy sprawdziłeś, czy jest możliwe użycie opcji push.defaulti branch.<name>.mergew git-config (1) ?
5
Mam push.defaultustawiony current- to w jaki sposób mogę to powiedzieć git push originbez refspec lub prąd. Ale to nie pomaga w automatycznym ustawianiu upstream.
John

Odpowiedzi:

66

Możesz to skonfigurować za git configpomocą git config --global push.default current.

Dokumenty: https://git-scm.com/docs/git-config/#Documentation/git-config.txt-pushdefault

Andrea Bergonzo
źródło
9
Mam taki zestaw - tak mogę po prostu powiedzieć git push originbez refspec lub upstream. Ale to nie pomaga w automatycznym ustawianiu upstream.
John
Działa dla mnie: +1:
Tim Strijdhorst
1
Tak, jak mówi @John, ważne jest, aby pamiętać, że nie powoduje to, że lokalny oddział śledzi zdalny; po prostu tworzy zdalną gałąź o tej samej nazwie, co lokalna.
waldyrious
Wystarczająco dobre, jeśli tylko potrzebujesz push, np. Tylko jeden programista jest w swoim oddziale, który edytuje tylko jedną kopię repozytorium.
superarts.org
29

Ponieważ nie sądzę, aby było to możliwe przy użyciu git config, oto co możesz zrobić w bash:

[[ $(git config "branch.$(git rev-parse --abbrev-ref HEAD).merge") = '' ]] && git push -u || git push

Jeśli bieżąca gałąź ma zdalną gałąź śledzenia, wywołuje w git pushprzeciwnym razie git push -u

mechaniczna ryba
źródło
24
Teraz możesz to zrobić git config --global push.default current.
Andrea Bergonzo,
2
@AndreaBergonzo to jedyna dobra odpowiedź, czy możesz ją dodać jako odpowiedź?
pdem
8
@AndreaBergonzo, @pdem - zwróć uwagę, że push.default=currenttworzy tylko oddział w zdalnym repozytorium o tej samej nazwie co oddział lokalny, ale nie ustawia lokalnego oddziału do śledzenia zdalnego. Nie wiem, dlaczego tak jest, ale warto o tym pamiętać.
waldyrious
23

Uwaga: fakt, że nowa domyślna polityka " simple" wypychania polega na odgałęzieniu posiadającym gałąź upstream oznacza, że:
ustawienie gałęzi upstream jest postrzegane jako krok dobrowolny, a nie ukryty automatyczny

Kiedy " git push [$there]" nie mówi, co pchnąć, używaliśmy dotychczas tradycyjnej semantyki "dopasowywania" (wszystkie twoje gałęzie zostały wysłane do pilota, o ile istnieją już gałęzie o tej samej nazwie).

Będziemy używać simplesemantyki " ", która wypycha bieżącą gałąź do gałęzi o tej samej nazwie, tylko wtedy , gdy bieżąca gałąź jest ustawiona na integrację z tą zdalną gałęzią . Aby to zmienić,
istnieje zmienna konfiguracyjna preferencji użytkownika „ push.default”.


Więc budowanie z mechanicalfish „s odpowiedzi , można zdefiniować alias, z odpowiednimi cudzysłowach ( ") uciekł ( \"):

git config alias.pu "![[ $(git config \"branch.$(git rev-parse --abbrev-ref HEAD).merge\") = '' ]] && git push -u || git push"

git pu origin

Sc0ttyD proponuje w komentarzach następujący alias:

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'

W wielu wierszach:

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && 
           git push -u origin $(git symbolic-ref --short HEAD) || 
           git push'
VonC
źródło
1
Dzięki za pokazanie, jak skonfigurować alias. Nie mam jednak jasności co do związku z pierwszą częścią Twojej odpowiedzi lub jej znaczenia.
John
2
@John, chodzi mi o to: ominiesz krok, który powinien być zamierzony. Możesz ustawić ten alias, ale chciałem wyjaśnić innym czytelnikom, dlaczego -uistnieje ta jawna opcja i dlaczego nie ma konfiguracji umożliwiającej automatyczne ustawienie tej opcji (stąd alias).
VonC,
2
Mam listę aliasów zsh w moim pliku .zshrc. Zmodyfikowałem tę odpowiedź, aby utworzyć następujący alias zsh:alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'
Sc0ttyD
2
@ Sc0ttyD Ciekawe, dziękuję. W odpowiedzi zawarłem Twój komentarz, aby uzyskać lepszą widoczność.
VonC,
20

Miałem ten sam problem. Znalazłem ten alias (.gitconfig)

[alias] track = "!git branch --set-upstream-to=origin/`git symbolic-ref --short HEAD`"

Użycie: git trackraz na nowy oddział (obecnie wyrejestrowany). Następnie pchnij jak zwykle :)

Frexuz
źródło
15

Odpowiedzi @VonC i @Frexuz są pomocne, ale oba ich rozwiązania powodują dla mnie błąd. Korzystając z obu odpowiedzi, zebrałem razem coś, co działa dla mnie:

    [alias]
    pu = ![[ $(git config "branch.$(git symbolic-ref --short HEAD).merge") = '' ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push

Powoduje to wykonanie git push -u origin $BRANCHNAMElub git push, w zależności od tego, czy jego nadrzędny (propertybranch.$BRANCHNAME.merge zdefiniowano ).

Wprowadzenie tego aliasu w wierszu poleceń będzie wymagało kodów ucieczki, więc prawdopodobnie najłatwiej jest użyć edytora do wstawienia do odpowiedniego pliku ( $HOME/.gitconfig(globalny), .git/config(lokalny) lub /etc/gitconfig(system))

znak
źródło
3
To najprostsza i najpełniejsza odpowiedź. Aby otworzyć domyślny edytor bez szukania pliku, możeszgit config --global -e
Adam Tolley,
5

Rozwiązałem ten problem za pomocą tego prostego skryptu Bash. Nie będzie działać na istniejących gałęziach, ale jeśli utworzysz wszystkie swoje gałęzie za pomocą tej funkcji, zawsze będziesz mieć automatycznie ustawioną gałąź nadrzędną.

function con { git checkout -b $1 && git push --set-upstream origin $1; }

$ 1 reprezentuje pierwszy argument, po którym przekazujesz, conwięc wygląda to tak, jak robisz:

git checkout -b my-new-branch && git push -u my-new-branch

... robiąc to po prostu:

con my-new-branch
JT Jobe
źródło
5

Krótka odpowiedź

Jeśli faktycznie lubisz być wyraźny i korzystasz z -uopcji, gdy jest to konieczne, ale po prostu nie chcesz wpisywać całości:

git push -u origin foo

Następnie możesz użyć następującego aliasu:

[alias]
    push-u = !git push -u origin $(git symbolic-ref --short HEAD)

I po prostu wpisz:

git push-u

Długa odpowiedź

Zazwyczaj potrzeba -u(shorthand for --set-upstream) występuje, gdy właśnie utworzyliśmy nową gałąź lokalną i zatwierdzenie, a chcemy wypchnąć to w górę. Zdalne repozytorium nie ma jeszcze nowej gałęzi, więc musimy powiedzieć gitowi, aby utworzył i śledził zdalną gałąź przed wypchnięciem zatwierdzenia. Jest to konieczne tylko przy pierwszym pchnięciu gałęzi. Oto typowy scenariusz:

git checkout -b foo         # Create local branch
git commit -m "Foo"         # Create local commit
git push -u origin foo      # Create and track remote branch, and push commit
git commit -m "Bar"         # Create local commit
git push                    # Push commit

Osobiście lubię potrzebę wyraźnego wyrażenia się git push -upodczas tworzenia zdalnego oddziału: jest to dość znacząca operacja, udostępniająca światu zupełnie nową gałąź.

Jednak nienawidzę tego, że musimy wyraźnie pisać git push -u origin foo. Nie tylko jest to trudne do wpisania, ale co ważniejsze, jest dość podatne na błędy! Podczas wpisywania nazwy oddziału łatwo jest popełnić błąd, a nowy oddział zdalny nie będzie miał takiej samej nazwy jak oddział lokalny! W większości przypadków naprawdę chcesz, aby repozytorium zewnętrzne byłoorigin , a gałąź nadrzędna miała taką samą nazwę jak gałąź lokalna.

Dlatego używam w moim aliasie .gitconfig, który jest podzbiorem doskonałej odpowiedzi udzielonej przez Marka :

[alias]
    push-u = !git push -u origin $(git symbolic-ref --short HEAD)

Teraz możemy wykonać następujące czynności, które nadal są jawne, ale mniej podatne na błędy:

git checkout -b foo         # Create local branch
git commit -m "Foo"         # Create local commit
git push-u                  # Create and track remote branch, and push commit
git commit -m "Bar"         # Create local commit
git push                    # Push commit
Boris Dalstein
źródło
3

Po prostu:

$ alias gush="git push -u origin HEAD"
djanowski
źródło
2
Tytuł pytania: "Jak skonfigurować git push, aby automatycznie ustawiał nadrzędny strumień bez -u?" Opis: „Wiem o git push -u, ale…”. Więc to nie odpowiada na pytanie.
Jan
2
@John Zaktualizowałem swoją odpowiedź, sugerując prosty alias.
djanowski
2
@John Czy teraz odpowiada na pytanie?
djanowski
1
@ ILI4SK4RIM Dzięki, to szaleństwo, że moja odpowiedź jest najprostsza, ale jest -1 ¯_ (ツ) _ / ¯
djanowski
2

Jeśli chcesz używać wbudowanych funkcji git tylko przy mniejszym możliwym naciśnięciu klawisza, po prostu wpisz:

$ git push -u o tab H tab

a autouzupełnianie da ci $ git push -u origin HEAD

Aby włączyć autocomplate na OSX, skonfiguruj ~/.git-completition.bashplik z tą zawartością i dodaj następujące wiersze do ~/.bash_profilepliku i zrestartuj terminal:

# git branch autocomplete
if [ -f ~/.git-completion.bash ]; then
  . ~/.git-completion.bash
fi
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Wpływa również na wbudowane terminale, takie jak ten w vscode itp.

gazdagergo
źródło
1
autouzupełnienie? git nie ma autouzupełniania. Twoja powłoka (bash? Zsh?) Ma załadowany zestaw reguł autouzupełniania. Czy możesz podać informacje dotyczące używanego zestawu reguł autouzupełniania i gdzie je zdobyć?
vy32
Och, w gruncie rzeczy dzięki. Ukończyłem odpowiedź z ustawieniami autouzupełniania.
gazdagergo
Bez znajomości zawartości twojego pliku ~ / .git-Complete.bash, twoja odpowiedź nie podlega operacjonalizacji.
vy32
1
Słuszna uwaga. Znalazłem źródło mojej git-completition.bashi dodałem do mojej odpowiedzi.
gazdagergo
1

Zrobiłem rozszerzenie git z przydatnymi skryptami, w tym ten:

usage: git line push

Push the current branch and set an upstream if needed.

https://github.com/jvenezia/git-line

jvenezia
źródło
0

Jeśli z jakiegokolwiek powodu żadna z pozostałych odpowiedzi nie działa dla Ciebie, możesz zastąpić git pushtę funkcję bash, aby automatycznie ponownie wysłać żądanie push z poprawnymi flagami, gdy jest to konieczne.

gitpush()
{
    git push -v 2>&1 | # perform push command, pipe all output
    tee /dev/tty | # keep output on screen and pipe it forward
    (
     cmd=$(sed -n "s/^.*\(git push --set-upstream origin .*\)$/\1/p");
     [[ -n "${cmd// }" ]] && (echo "> $cmd"; eval $cmd);
    ) # if we get output that matches the command to perform, execute it
}

Będziesz poświęcał część postępu w wynikach wypychania, ale poza tym wszystko działa zgodnie z oczekiwaniami.

Osobiście będę korzystał z odpowiedzi JT Jobe .

iamfrank
źródło