Hành vi mặc định của Dịch vụ git đẩy mà không có chi nhánh được chỉ định


1366

Tôi sử dụng lệnh sau để đẩy đến chi nhánh từ xa của mình:

git push origin sandbox

Nếu tôi nói

git push origin

điều đó có thúc đẩy thay đổi trong các chi nhánh khác của tôi không, hay nó chỉ cập nhật chi nhánh hiện tại của tôi? Tôi có ba nhánh: master, productionsandbox.

Các git pushtài liệu không rõ ràng về điều này, vì vậy tôi muốn làm rõ điều này cho tốt.

Những nhánh và điều khiển từ xa nào thực hiện các git pushlệnh sau đây cập nhật chính xác?

git push 
git push origin

origin ở trên là một điều khiển từ xa.

Tôi hiểu rằng git push [remote] [branch]sẽ chỉ đẩy chi nhánh đó đến điều khiển từ xa.


Về cấu hình của các công cụ diff nói chung và tập lệnh mới git Difftool, tôi đã thêm một câu trả lời mới trong câu hỏi SO khác này: stackoverflow.com/questions/255202/
Lỗi

67
Tôi đã viết một bài blog về hành vi đáng ngạc nhiên git push, có thể được quan tâm
Mark Longair

1
@Mark: trong công việc khác, chỉ đẩy chi nhánh hiện tại lên thượng nguồn được theo dõi. Đẹp.
VonC


help.github.com/articles/pushing-to-a-remote đặt liên kết này ở đây để được giúp đỡ ngay lập tức cho những người mới như tôi
MycrofD

Câu trả lời:


1591

Bạn có thể kiểm soát hành vi mặc định bằng cách đặt Push.default trong cấu hình git của bạn. Từ tài liệu git-config (1) :

push.default

Xác định hành động git đẩy sẽ thực hiện nếu không có refspec nào được đưa ra trên dòng lệnh, không có refspec nào được cấu hình trong điều khiển từ xa và không có refspec nào được ngụ ý bởi bất kỳ tùy chọn nào được đưa ra trên dòng lệnh. Các giá trị có thể là:

  • nothing: đừng đẩy bất cứ điều gì

  • matching: đẩy tất cả các nhánh phù hợp

    Tất cả các chi nhánh có cùng tên ở cả hai đầu được coi là phù hợp.

    Điều này từng là mặc định, nhưng không phải vì Git 2.0 ( simplelà mặc định mới).

  • upstream: đẩy nhánh hiện tại lên nhánh ngược dòng của nó ( trackinglà từ đồng nghĩa không dùng nữa cho ngược dòng)

  • current: đẩy nhánh hiện tại đến một nhánh cùng tên

  • simple: (mới trong Git 1.7.11) như ngược dòng, nhưng từ chối đẩy nếu tên của nhánh ngược dòng khác với tên cục bộ

    Đây là lựa chọn an toàn nhất và rất phù hợp cho người mới bắt đầu.

    Chế độ này đã trở thành mặc định trong Git 2.0.

Các chế độ đơn giản, hiện tại và ngược dòng dành cho những người muốn đẩy ra một nhánh duy nhất sau khi hoàn thành công việc, ngay cả khi các nhánh khác chưa sẵn sàng để bị đẩy ra

Ví dụ dòng lệnh:

Để xem cấu hình hiện tại:

git config --global push.default

Để đặt cấu hình mới:

git config --global push.default current

11
Có lẽ đáng chú ý rằng đây là tính năng mới trong v1.6.3: kernel.org/pub/software/scm/git/docs/RelNotes-1.6.3.txt
CB Bailey

8
"Push.default" này là điều tuyệt vời nhất từng có khi làm việc với nhiều repos. Đặt nó thành "theo dõi" và tất cả các bạn đều tốt. Kết hợp với nhánh - thiết lập ngược dòng giúp cho việc đẩy và kéo thuận tiện hơn.
jpswain

13
"theo dõi" là từ đồng nghĩa không dùng cho "ngược dòng": kernel.org/pub/software/scm/git/docs/git-config.html
LuckyMalaka

22
Điều đáng chú ý là vào ngày 1.7.11, có một simplechế độ mới . Chế độ này được dự định để trở thành mặc định trong tương lai. simplehoạt động như thế upstream, nhưng giống như currentyêu cầu rằng các tên nhánh giống nhau ở cả hai đầu.
Kai

9
Điều đáng chú ý là kể từ Git 2.0, simplehành vi hiện là mặc định.
do0g

209

Bạn có thể thiết lập hành vi mặc định cho git của mình bằng push.default

git config push.default current

hoặc nếu bạn có nhiều kho lưu trữ và muốn giống nhau cho tất cả thì

git config --global push.default current

Dòng điện trong thiết lập này có nghĩa là theo mặc định, bạn sẽ chỉ đẩy nhánh hiện tại khi bạn thực hiện git đẩy

Các tùy chọn khác là:

  • không có gì: Đừng đẩy bất cứ điều gì
  • khớp: Đẩy tất cả các nhánh khớp (mặc định)
  • theo dõi: Đẩy chi nhánh hiện tại đến bất cứ thứ gì nó đang theo dõi
  • hiện tại: Đẩy chi nhánh hiện tại

CẬP NHẬT - CÁCH MỚI ĐỂ LÀM ĐIỀU NÀY

Kể từ Git 1.7.11, hãy làm như sau:

git config --global push.default simple

Đây là một cài đặt mới được giới thiệu hoạt động giống như hiện tại và sẽ được đặt mặc định thành git từ v 2.0 theo tin đồn


29
Vâng, tôi đã đọc câu trả lời mà bạn đang đề cập, nhưng câu trả lời đó chỉ cho biết phải làm gì chứ không phải làm thế nào. Vì vậy, tôi đã thêm câu trả lời của mình để tất cả thông tin cần thiết để thiết lập nó nằm trên cùng một trang.
Christoffer

3
ĐỒNG Ý; tốt hơn là đề xuất một chỉnh sửa cho bài đăng đã nói, bởi vì không ai sẽ thấy câu trả lời của bạn, vì nó không có khả năng nhận được nhiều phiếu bầu
CharlesB

Làm thế nào một người sẽ đi về kéo đến chi nhánh hiện tại? Git kéo xuất xứ?
Francois

200

git push originsẽ đẩy tất cả các thay đổi trên các nhánh cục bộ phù hợp với các nhánh từ xa tại originAs forgit push

Hoạt động như git push <remote>, <remote>từ xa của nhánh hiện tại (hoặc nguồn gốc, nếu không có điều khiển từ xa được cấu hình cho nhánh hiện tại).

Từ phần Ví dụ của git-pushtrang người đàn ông


2
Đúng, điều đó làm cho nó rõ ràng. Có lẽ tôi đang chạy phiên bản cũ hơn của git (1.6.1.1 Mac OS X) không có các ví dụ này trong trang man.
Bệnh dịch hạch

Có lẽ tôi đang chạy 1.6.3.1. Tôi đã tìm thấy nó trên các trang web tôi liên kết tuy nhiên.
baudtack

2
Vì vậy, trong trường hợp của tôi, khi tất cả các nhánh cục bộ có cùng "nguồn gốc", "git đẩy" sẽ giống hệt như "git đẩy gốc" sẽ chỉ đẩy các nhánh cục bộ có nhánh tương ứng trong điều khiển từ xa.
Bệnh dịch hạch

@Debajit Đúng rồi! Bằng cách này, câu hỏi tuyệt vời. Tôi đã luôn luôn cho rằng git đẩy sẽ chỉ đẩy chi nhánh hiện tại. Rõ ràng là không! Rất tốt để biết.
baudtack

5
Câu hỏi này đã cũ nhưng đối với bất kỳ ai mới, @docgnome đều đúng. Chỉ cần chạy 'git đẩy gốc' sẽ đẩy tất cả các nhánh thay vì chỉ nhánh hiện tại. Sử dụng 'git đẩy -f -v -n phát triển nguồn gốc' để buộc đẩy một nhánh có tên là phát triển. Sử dụng cờ -n để mô phỏng kết quả đẩy git để bạn có thể thấy trước chi nhánh nào sẽ bị ảnh hưởng. Nếu nó trông ổn thì hãy chạy 'git đẩy -f -v phát triển nguồn gốc'. Điều này có thể hữu ích stackoverflow.com/questions/3741136/git-push-f-vs
Dylan Valade

54

Tôi vừa cam kết mã của mình với một chi nhánh và đẩy nó vào github, như thế này:

git branch SimonLowMemoryExperiments
git checkout SimonLowMemoryExperiments
git add .
git commit -a -m "Lots of experimentation with identifying the memory problems"
git push origin SimonLowMemoryExperiments

3
Bạn có thể ngưng tụ cam kết với `git commit -am" ... "`
James Harrington

17
Câu trả lời này có liên quan gì đến câu hỏi không ?? :?
Asim KT

26

Đây là một thông tin rất hữu ích và hữu ích về Git Push : Git Push: Chỉ là Mẹo

Việc sử dụng git đẩy phổ biến nhất là đẩy các thay đổi cục bộ của bạn lên kho lưu trữ ngược dòng công khai. Giả sử rằng thượng nguồn là một điều khiển từ xa có tên "origin" (tên từ xa mặc định nếu kho lưu trữ của bạn là một bản sao) và nhánh được cập nhật thành / từ được đặt tên là "master" (tên nhánh mặc định), điều này được thực hiện với:git push origin master

git push origin sẽ đẩy các thay đổi từ tất cả các nhánh cục bộ để khớp các nhánh từ xa gốc.

git push origin master sẽ đẩy các thay đổi từ nhánh chính cục bộ sang nhánh chính từ xa.

git push origin master:staging sẽ đẩy các thay đổi từ nhánh chính cục bộ sang nhánh dàn từ xa nếu nó tồn tại.


git push origin branch_namevì một số lý do, không chỉ đẩy branch_namechi nhánh mà còn các chi nhánh địa phương khác của tôi (phiên bản git 1.9.1).
mrgloom

git push origin master:staginglà một viên ngọc ẩn tuyệt vời!
Shakeel

19

(Tháng 3 năm 2012)
Cẩn thận: matchingchính sách " " mặc định đó có thể thay đổi sớm
(đôi khi sau git1.7.10 +)
:

Xem " Vui lòng thảo luận:" git đẩy "nên làm gì khi bạn không nói phải đẩy cái gì? "

Trong cài đặt hiện tại (nghĩa là push.default=matching), git pushkhông có đối số sẽ đẩy tất cả các nhánh tồn tại cục bộ và từ xa có cùng tên .
Điều này thường thích hợp khi nhà phát triển đẩy vào kho lưu trữ công khai của riêng mình, nhưng có thể gây nhầm lẫn nếu không nguy hiểm khi sử dụng kho lưu trữ được chia sẻ.

Đề xuất là thay đổi mặc định thành ' upstream' , tức là chỉ đẩy nhánh hiện tại và đẩy nó sang nhánh git kéo sẽ kéo từ đó.
Một ứng cử viên khác là ' current'; điều này chỉ đẩy nhánh hiện tại đến nhánh từ xa cùng tên.

Những gì đã được thảo luận cho đến nay có thể được nhìn thấy trong chủ đề này:

http://thread.gmane.org/gmane.comp.version-control.git/192547/f Focus = 192694

Các cuộc thảo luận liên quan trước đây bao gồm:

Để tham gia thảo luận, hãy gửi tin nhắn của bạn đến: git@vger.kernel.org


18

Tôi chỉ cần đặt nó trong phần bí danh .gitconfig của tôi và thích cách nó hoạt động:

pub = "!f() { git push -u ${1:-origin} `git symbolic-ref HEAD`; }; f"

Sẽ đẩy chi nhánh hiện tại về nguồn gốc với git pubhoặc một repo khác với git pub repo-name. Ngon.


4
Điều đó thật tuyệt, nhưng thật không may, giả định rằng chi nhánh có cùng tên trên kho lưu trữ khác. Hãy thử git push -u --repo="origin" $1;thay thế. Nó hoạt động khá tốt, ngoại trừ nếu bạn đẩy sang kho lưu trữ khác, tên nhánh sẽ là tên được sử dụng bởi kho lưu trữ khác, không phải tên bạn đang đẩy từ
Casebash

Này cảm ơn nhé! Làm cho tôi muốn làm một phiên bản hoàn chỉnh hơn để kiểm tra trạng thái theo dõi trước khi đẩy. Nhưng bây giờ tôi sẽ gắn bó với tôi vì tôi hiếm khi có các tên nhánh khác nhau giữa các repos.
Mat Schaffer

10

Bạn có thể đẩy chi nhánh hiện tại bằng lệnh

git push origin HEAD

(lấy từ đây )


8

Một git đẩy sẽ cố gắng và đẩy tất cả các chi nhánh địa phương đến máy chủ từ xa, đây có thể là điều bạn không muốn. Tôi có một vài thiết lập tiện lợi để giải quyết vấn đề này:

Bí danh "gpull" và "gpush" một cách thích hợp:

Trong ~ / .bash_profile của tôi

get_git_branch() {
  echo `git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
}
alias gpull='git pull origin `get_git_branch`'
alias gpush='git push origin `get_git_branch`'

Do đó, việc thực thi "gpush" hoặc "gpull" sẽ chỉ đẩy chi nhánh "hiện tại" của tôi.


3
Nếu bạn luôn muốn hành vi của gpush, bạn cũng có thể đặt remote.origin.push = HEAD (ví dụ: "git config remote.origin.push HEAD"), như đã đề cập trong phần ví dụ của trang git-push man.
Trevor Robinson

5
Điều này là không cần thiết nếu bạn xem bài viết trên của "Brian L".
jpswain

1
Đó là, như không có Equv. cho pull pull.default
Samoody

8

Bạn có thể thay đổi hành vi mặc định đó trong .gitconfigví dụ:

[push]
  default = current

Để kiểm tra cài đặt hiện tại, hãy chạy:

git config --global --get push.default

3

Thay vì sử dụng các bí danh, tôi thích tạo các tập lệnh git-XXX để tôi có thể kiểm soát nguồn dễ dàng hơn (tất cả các nhà phát triển của chúng tôi đều có một thư mục được kiểm soát nguồn nhất định trên đường dẫn của họ cho loại điều này).

Tập lệnh này (được gọi git-setpush) sẽ đặt giá trị cấu hình cho remote.origin.pushgiá trị thành thứ sẽ chỉ đẩy nhánh hiện tại:

#!/bin/bash -eu

CURRENT_BRANCH=$(git branch | grep '^\*' | cut -d" " -f2)
NEW_PUSH_REF=HEAD:refs/for/$CURRENT_BRANCH

echo "setting remote.origin.push to $NEW_PUSH_REF"
git config remote.origin.push $NEW_PUSH_REF

lưu ý, khi chúng tôi đang sử dụng Gerrit, nó đặt mục tiêu refs/for/XXXđẩy vào một nhánh đánh giá. Nó cũng giả sử nguồn gốc là tên từ xa của bạn.

Gọi nó sau khi kiểm tra một chi nhánh với

git checkout your-branch
git setpush

Nó rõ ràng có thể được điều chỉnh để thực hiện kiểm tra, nhưng tôi thích các kịch bản để làm một việc và làm tốt


thiết lập ý tưởng tuyệt vời remote.origin.push để sử dụng gerrit. feature/fix_fubarTất cả các nhánh tính năng cục bộ của tôi đều được trỏ đến các nhánh ngược dòng chung chung hơn masterhoặc develop, vì vậy điều này sẽ chỉ ra ở thượng nguồn sai. Dòng chảy cục bộ của bạn trông như thế nào đối với các repos được kiểm soát gerrit?
spazm

Nếu bạn chỉ có một nhánh "mục tiêu" trên gerrit, hãy thử đơn giản git config remote.origin.push HEAD:refs/for/master.
fracz

2

Tôi đã thêm các hàm sau vào tệp .bashrc để tự động hóa các tác vụ này. Nó không git đẩy / git pull + tên của chi nhánh hiện tại.

function gpush()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpush
git: for current branch: push changes to remote branch;
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git push ${bname}
    set +x
  fi
}

function gpull()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpull
git: for current branch: pull changes from
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git pull ${bname}
    set +x
  fi
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.