Bagaimana cara mengkonfigurasi git push agar secara otomatis mengatur upstream tanpa -u?

105

Saya ingin git push originmenyetel referensi upstream secara otomatis ketika saya mendorong cabang yang dibuat secara lokal untuk pertama kalinya.

Saya tahu tentang git push -u, tetapi saya tidak ingin memikirkan apakah saya telah menggunakan -usebelumnya atau tidak atau menyetel referensi upstream. Dengan kata lain, saya ingin git pushsecara otomatis mempengaruhi git push -usetiap dorongan dari cabang yang belum memiliki upstream.

Apakah ini mungkin? Jika itu membutuhkan alias atau skrip utilitas, itu bagus.

John
sumber
2
Sudahkah Anda memeriksa apakah mungkin untuk menggunakan opsi push.defaultdan branch.<name>.mergedi git-config (1) ?
5
Saya telah push.defaultmenetapkan current- begitulah cara saya mengatakan git push origintanpa refspec atau upstream. Tetapi itu tidak membantu dengan secara otomatis mengatur upstream.
Yohanes

Jawaban:

66

Anda dapat mengkonfigurasinya dengan git configmenggunakan git config --global push.default current.

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

Andrea Bergonzo
sumber
9
Saya memiliki set itu - itulah yang bisa saya katakan git push origintanpa refspec atau upstream. Tetapi itu tidak membantu dengan secara otomatis mengatur upstream.
Yohanes
Bekerja untuk saya: +1:
Tim Strijdhorst
1
Ya, seperti yang dikatakan @John, penting untuk diingat bahwa ini tidak membuat jalur cabang lokal menjadi remote; itu hanya membuat cabang jarak jauh dengan nama yang sama dengan cabang lokal.
waldyrious
Cukup bagus jika Anda hanya perlu push, misalnya hanya satu pengembang di cabangnya, yang hanya mengedit satu salinan repo.
superarts.org
29

Karena menurut saya ini tidak mungkin dilakukan menggunakan git config, inilah yang dapat Anda lakukan di bash:

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

Jika cabang saat ini memiliki cabang pelacakan jarak jauh, ia memanggil git pushsebaliknya git push -u

ikan mekanik
sumber
24
Sekarang Anda bisa melakukannya git config --global push.default current.
Andrea Bergonzo
2
@AndreaBergonzo ini adalah satu-satunya jawaban yang bagus untuk saya, dapatkah Anda menambahkannya sebagai jawaban?
pdem
8
@AndreaBergonzo, @pdem - perhatikan bahwa push.default=currenthanya membuat cabang di repositori jarak jauh dengan nama yang sama dengan cabang lokal, tetapi tidak mengatur cabang lokal untuk melacak cabang jarak jauh. Saya tidak yakin mengapa hal ini terjadi, tetapi perlu diingat.
waldyrious
23

Catatan: fakta bahwa kebijakan push default baru " simple" bergantung pada cabang yang memiliki cabang upstream berarti:
menyetel cabang upstream dipandang sebagai langkah sukarela, bukan langkah otomatis tersembunyi

Ketika " git push [$there]" tidak mengatakan apa yang harus didorong, sejauh ini kami telah menggunakan semantik "pencocokan" tradisional (semua cabang Anda dikirim ke remote selama sudah ada cabang dengan nama yang sama di sana).

Kita akan menggunakan simplesemantik " " yang mendorong cabang saat ini ke cabang dengan nama yang sama, hanya jika cabang saat ini diatur untuk berintegrasi dengan cabang jarak jauh itu .
Ada variabel konfigurasi preferensi pengguna " push.default" untuk mengubahnya.


Jadi membangun dari mechanicalfish 's jawaban , Anda dapat menentukan alias, dengan tanda kutip ganda kanan ( ") lolos ( \"):

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

git pu origin

Sc0ttyD mengusulkan di komentar alias berikut:

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

Dalam beberapa baris:

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && 
           git push -u origin $(git symbolic-ref --short HEAD) || 
           git push'
VonC
sumber
1
Terima kasih telah menunjukkan cara menyiapkan alias. Saya tidak jelas tentang hubungan atau relevansi bagian pertama dari jawaban Anda.
Yohanes
2
@ John Maksud saya adalah: Anda akan menghindari langkah yang seharusnya disengaja. Anda dapat mengatur alias itu, tetapi saya ingin menjelaskan kepada pembaca lain mengapa -uopsi eksplisit ini ada, dan mengapa tidak ada konfigurasi untuk membuat opsi tersebut otomatis (karenanya alias).
VonC
2
Saya memiliki daftar alias zsh di .zshrc saya. Saya mengubah jawaban ini untuk membuat alias zsh berikut: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 Menarik, terima kasih. Saya telah memasukkan komentar Anda dalam jawaban untuk visibilitas lebih lanjut.
VonC
20

Saya punya masalah yang sama. Saya telah menemukan alias ini (.gitconfig)

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

Penggunaan: git tracksekali per cabang baru (saat ini keluar). Kemudian tekan saja seperti biasa :)

Frexuz
sumber
15

Jawaban oleh @VonC dan @Frexuz sangat membantu, tetapi kedua solusi mereka menghasilkan kesalahan bagi saya. Menggunakan kedua jawaban mereka, saya menyusun sesuatu yang berhasil untuk saya:

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

Ini menghasilkan eksekusi salah satu git push -u origin $BRANCHNAMEatau git push, bergantung pada apakah upstreamnya (properti branch.$BRANCHNAME.merge) ditentukan.

Memasukkan alias ini pada baris perintah akan membutuhkan kode pelolosan, jadi mungkin paling mudah menggunakan editor untuk memasukkan ke file yang benar ( $HOME/.gitconfig(global), .git/config(lokal), atau /etc/gitconfig(sistem))

Menandai
sumber
3
Inilah jawaban yang paling lugas dan lengkap. Untuk membuka editor default tanpa mencari file, Anda dapatgit config --global -e
Adam Tolley
5

Saya memecahkan masalah ini dengan menggunakan skrip Bash sederhana ini. Ini tidak akan berfungsi pada cabang yang ada, tetapi jika Anda membuat semua cabang Anda dengan fungsi ini, Anda akan selalu mengatur cabang upstream Anda secara otomatis.

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

$ 1 mewakili argumen pertama yang Anda berikan setelahnya, conjadi ini seperti melakukan:

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

... dengan hanya melakukan ini:

con my-new-branch
JT Jobe
sumber
5

Jawaban singkat

Jika Anda benar-benar ingin eksplisit dan menggunakan -uopsi bila perlu, tetapi tidak ingin mengetik seluruhnya:

git push -u origin foo

Kemudian Anda dapat menggunakan alias berikut:

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

Dan cukup ketik:

git push-u

Jawaban panjang

Biasanya, kebutuhan -u(singkatan untuk --set-upstream) adalah ketika kita baru saja membuat cabang lokal baru dan melakukan, dan kita ingin mendorongnya ke atas. Repositori jarak jauh belum memiliki cabang baru, jadi kita perlu memberi tahu git untuk membuat dan melacak cabang jarak jauh sebelum mendorong komit. Ini hanya diperlukan untuk dorongan pertama di cabang. Berikut skenario tipikal:

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

Secara pribadi, saya suka kebutuhan untuk menjelaskan secara eksplisit git push -usaat membuat cabang jarak jauh: ini adalah operasi yang cukup signifikan, berbagi cabang baru ke dunia.

Namun, saya benci kita harus menulis secara eksplisit git push -u origin foo. Tidak hanya sulit untuk mengetik, tetapi yang lebih penting, ini cukup rawan kesalahan! Sangat mudah untuk membuat kesalahan saat mengetik nama cabang, dan cabang jarak jauh yang baru tidak akan memiliki nama yang sama dengan cabang lokal Anda! Dalam kebanyakan kasus, sebenarnya Anda ingin repositori upstream origin, dan cabang upstream memiliki nama yang sama dengan cabang lokal Anda.

Oleh karena itu, saya menggunakan alias berikut di my .gitconfig, yang merupakan bagian dari jawaban luar biasa yang diberikan oleh Mark :

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

Sekarang, kita dapat melakukan hal berikut, yang masih eksplisit, tetapi tidak terlalu rentan terhadap kesalahan:

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
sumber
3

Secara sederhana:

$ alias gush="git push -u origin HEAD"
djanowski
sumber
2
Judul pertanyaan: "Bagaimana cara mengkonfigurasi git push agar otomatis mengatur upstream tanpa -u?" Deskripsi: "Saya tahu tentang git push -u, tapi ...". Jadi ini tidak menjawab pertanyaan itu.
Yohanes
2
@ John Saya memperbarui jawaban saya untuk menyarankan alias sederhana.
djanowski
2
@ John Apakah itu menjawab pertanyaan sekarang?
djanowski
1
@ ILI4SK4RIM Terima kasih, sungguh gila bahwa jawaban saya adalah yang paling sederhana, namun -1 ¯_ (ツ) _ / ¯
djanowski
2

Jika Anda ingin menggunakan fitur git built-in hanya dengan sedikit kemungkinan menekan tombol, cukup ketik:

$ git push -u o tab H tab

dan pelengkapan otomatis akan memberi Anda $ git push -u origin HEAD

Untuk mengaktifkan pelengkapan otomatis di OSX, atur ~/.git-completition.bashfile dengan konten ini dan tambahkan baris berikut ke ~/.bash_profilefile Anda dan mulai ulang terminal Anda:

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

Ini mempengaruhi terminal built-in juga, seperti yang ada di vscode dll.

gazdagergo.dll
sumber
1
pelengkapan otomatis? git tidak memiliki pelengkapan otomatis. Shell Anda (bash? Zsh?) Memiliki seperangkat aturan pelengkapan otomatis yang dimuat. Dapatkah Anda memberikan informasi terkait kumpulan aturan pelengkapan otomatis yang Anda gunakan, dan di mana mendapatkannya?
vy32
Oh, terima kasih banyak. Saya telah menyelesaikan jawaban saya dengan pengaturan pelengkapan otomatis saya.
gazdagergo
Tanpa mengetahui konten file Anda ~ / .git-complete.bash, jawaban Anda tidak dapat dioperasikan.
vy32
1
Poin yang bagus. Saya menemukan sumber saya git-completition.bashdan menambahkan jawaban saya.
gazdagergo
1

Saya membuat ekstensi git dengan skrip yang berguna, termasuk yang ini:

usage: git line push

Push the current branch and set an upstream if needed.

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

jvenezia
sumber
0

Jika, karena alasan apa pun, tidak ada jawaban lain yang sesuai untuk Anda, maka Anda dapat mengganti git pushdengan fungsi bash ini untuk mengirim ulang permintaan push secara otomatis dengan flag yang benar saat diperlukan.

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
}

Anda akan mengorbankan bagian kemajuan dari keluaran push, tetapi selain itu semuanya berfungsi seperti yang diharapkan.

Secara pribadi, saya akan menggunakan jawaban JT Jobe .

iamfrank
sumber