Thay đổi HEAD điều khiển từ xa Git để trỏ đến một cái gì đó ngoài cái chính


124

Làm cách nào để đặt tham chiếu HEAD của điều khiển từ xa Git trỏ đến một thứ ngoài "chủ"?

Dự án của tôi có chính sách không sử dụng nhánh "chính" (tất cả các nhánh phải có tên có nghĩa). Hơn nữa, kho lưu trữ chính quy tắc chỉ có thể truy cập được qua ssh: //, không có quyền truy cập shell (như GitHub hoặc Unfuddle).

Vấn đề của tôi là kho lưu trữ từ xa vẫn có tham chiếu HEAD tới refs / heads / master, nhưng tôi cần nó trỏ đến một nhánh khác. Điều này gây ra hai vấn đề:

  1. Khi sao chép repo, ở đó,

    cảnh báo: HEAD từ xa đề cập đến giới thiệu không tồn tại, không thể thanh toán.

    Thật khó hiểu và bất tiện.

  2. Trình duyệt mã dựa trên web phụ thuộc vào HEAD làm cơ sở để duyệt cây. Khi đó, tôi cần HEAD trỏ đến một nhánh hợp lệ.


Chỉ thêm một khả năng cho bản ghi, nhưng không phù hợp với trường hợp của bạn.
VonC 28/09/09

thủ thuật "không-chung-tổ-tiên": thú vị. Bạn có thể đăng nó như một câu trả lời chi tiết và chọn nó làm câu trả lời chính thức nếu bạn thấy nó hoạt động.
VonC

12
FWIW, vì bạn đã đề cập đến GitHub trong câu hỏi - nếu bạn muốn thay đổi tài liệu tham khảo HEAD trên GitHub, chỉ cần chuyển đến màn hình "Quản trị" của kho lưu trữ và thay đổi menu thả xuống "Chi nhánh mặc định" thành bất kỳ nhánh nào bạn muốn HEAD trỏ đến.
Joe


Câu trả lời:


63

Gần như có câu hỏi tương tự trên GitHub một năm trước.

Ý tưởng là đổi tên nhánh chính:

git branch -m master development
git branch -m published master
git push -f origin master 

Làm chủ có những gì bạn muốn mọi người sử dụng và làm tất cả các công việc khác trong các chi nhánh.

(" git-symbolic-ref HEAD refs/head/published" sẽ không được truyền đến repo từ xa)

Điều này tương tự như " Làm cách nào để xóa origin / master trong Git ".


Như đã nói trong chủ đề này : (nhấn mạnh của tôi)

" git clone" chỉ tạo một nhánh cục bộ duy nhất.
Để làm điều đó, nó sẽ xem xét HEAD refrepo từ xa và tạo một nhánh cục bộ có cùng tên với nhánh từ xa được nó tham chiếu.

Vì vậy, để kết thúc điều đó, bạn có repo A và sao chép nó:

  • HEADtham chiếu refs/heads/mastervà tồn tại
    -> bạn nhận được một nhánh cục bộ được gọi là master, bắt đầu từ origin / master

  • Tham chiếu HEAD refs/heads/anotherBranchvà tồn tại
    -> bạn nhận được một nhánh cục bộ được gọi anotherBranch, bắt đầu từorigin/anotherBranch

  • Tham chiếu HEAD refs/heads/mastervà điều đó không tồn tại
    -> "git clone" khiếu nại

Không chắc liệu có bất kỳ cách nào để sửa đổi trực tiếp HEADref trong repo hay không .

(đó là tất cả các điểm của câu hỏi của bạn, tôi biết;))


Có lẽ cách duy nhất sẽ là một "ấn phẩm cho người nghèo" , nơi bạn:

 $ git-symbolic-ref HEAD refs/head/published
 $ git-update-server-info
 $ rsync -az .git/* server:/local_path_to/git/myRepo.git/

Nhưng điều đó sẽ liên quan đến quyền ghi vào máy chủ, điều này không phải lúc nào cũng có thể thực hiện được.


Như tôi giải thích trong " Git: Cách đúng để thay đổi Active Branch trong kho lưu trữ trống? ", git remote set-headSẽ không thay đổi bất kỳ điều gì trên kho lưu trữ từ xa.

Nó sẽ chỉ thay đổi nhánh theo dõi từ xa được lưu trữ cục bộ trong repo cục bộ của bạn, trong remotes/<name>/HEAD.


Cảm ơn, VonC. Tôi đọc nó trước khi đăng ở đây. Nhưng như bạn có thể thấy, một nhánh được gọi là "chủ" không được chào đón trong dự án này vì lý do kỹ thuật và chính sách.
JasonSmith

Sau đó, bạn có thể thực thi chính sách đó bằng cách không cho phép bất kỳ cập nhật nào trên nhánh chính thông qua một móc cam kết trước.
VonC 28/09/09

Vâng, nếu hóa ra không có cách nào để làm những gì tôi muốn thì tôi sẽ làm chính xác điều đó và chấp nhận câu trả lời của bạn. Cảm ơn đã theo dõi!
JasonSmith 28/09/09

Cảm ơn các cập nhật. Hiện tại, tôi đã sử dụng thủ thuật "không có tổ tiên chung" để tạo một nhánh chính chỉ với một lần cam kết. (Tức là: git branch -D master; echo ref: refs / heads / master> .git / HEAD; rm *). Sau đó, tôi chỉ cần chạm vào một tệp có tên GO_AWAY và thông báo cam kết giải thích tình huống. Điều đó sẽ hoạt động ngay bây giờ. Tôi có thể kiểm tra qua nguồn và truy tìm nơi bên nhận đặt HEAD để có câu trả lời cuối cùng.
JasonSmith

1
@ctn Đó chỉ đơn giản là vì tôi quên tùy chọn -f( --force). Tôi đã chỉnh sửa câu trả lời cho phù hợp. Sau đó, câu trả lời bạn tham chiếu sử dụng cùng một tùy chọn.
VonC

42

Cập nhật: Điều này chỉ hoạt động đối với bản sao cục bộ của kho lưu trữ ("máy khách"). Hãy xem bình luận của người khác bên dưới.

Với phiên bản git gần đây (tháng 2 năm 2014), quy trình chính xác sẽ là:

git remote set-head $REMOTE_NAME $BRANCH

Vì vậy, ví dụ, chuyển đầu trên điều khiển từ xa originsang chi nhánh developsẽ là:

git remote set-head origin develop


Tính năng này cần phiên bản git gần đây trên máy chủ hay là đủ nếu máy khách đã cài đặt git gần đây?
Mikko Rantalainen

3
@Totor là ngắn gọn nhưng đúng; câu trả lời này nên được phản đối. Git có khái niệm hơi khó hiểu này về một "cục bộ, nhánh mặc định cho điều khiển từ xa". Nó cho phép bạn gõ "origin" thay vì "origin / defaultbranch" và là một thứ thuần túy phía máy khách . Truyện dài tại git-scm.com/docs/git-remote # set-head
MarcH

1
để xác nhận những gì @MarchH đang nói về: run git checkout -b default; git push origin HEAD; git remote set-head origin default. Sau đó, bạn có thể kiểm tra các thay đổi cục bộ với cat .git/refs/remotes/origin/HEAD(nên có ref: refs/remotes/origin/default) và thiếu các thay đổi từ xa với git remote show origin(nó vẫn sẽ là bất kỳ thứ gì trước khi bạn thêm nhánh mặc định).
De Novo

37

Vì bạn đề cập đến GitHub, để làm điều đó trên trang web của họ, chỉ cần vào dự án của bạn, sau đó ...

admin > Default Branch > (choose something)

Làm xong.


1
Thông minh! Đó là chút cuối cùng còn thiếu.
berkus

Nguồn gốc / HEAD của tôi đã trỏ đến một nhánh tính năng thay vì chính. Tôi đã thử thay đổi "nhánh chính" qua lại, nhưng nó không ảnh hưởng đến HEAD ... Bất kỳ đề xuất?
Daniil SheELECTv

3
Cài đặt> Chi nhánh> Chi nhánh mặc định
Chun Yang

12

Xem: http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

Điều này đặt nhánh mặc định trong kho lưu trữ git. Bạn có thể chạy điều này trong kho lưu trữ trống hoặc được nhân bản.

Sử dụng:

$ git symbolic-ref HEAD refs/heads/<branch name>

6
$ git Symbol-ref HEAD refs / heads / name-of-branch
Lamy

Tôi đã làm điều này trong repo từ xa của mình và nó đã khắc phục sự cố của tôi sao chép vì lý do nào đó mà đầu là tên nhánh khác và do đó cố gắng sao chép bản chính sẽ dẫn đến lỗi trong khi cố gắng đóng bản chính trong trình soạn nhạc, điều này có thể rất cụ thể cho trường hợp này , nhưng những người khác có thể là ở vị trí đó và tự hỏi phải làm gì
Christopher Thomas

10

(Về cơ bản đã có cùng một câu hỏi " tạo một tham chiếu biểu tượng git trong kho lưu trữ từ xa ", câu hỏi này không nhận được câu trả lời chung.)

Nhưng có một câu trả lời cụ thể cho các "trang trại" git khác nhau (nơi nhiều người dùng có thể quản lý git repo thông qua giao diện hạn chế: qua http và ssh): http://Github.com , http://Gitorious.org , http: / /repo.or.cz , Girar ( http://git.altlinux.org ).

Những câu trả lời cụ thể này có thể hữu ích cho những người đọc trang này và suy nghĩ về các dịch vụ cụ thể này.


4
Giờ đây, họ có một menu thả xuống để chọn chi nhánh HEAD tại repo.or.cz (ví dụ: repo.or.cz/editproj.cgi?name=for-me-and-for-all_imz.git ) và gitorious.org , quá. Tuyệt quá!
imz - Ivan Zakharyaschev

7

Nếu bạn có quyền truy cập vào repo từ xa từ một trình bao, chỉ cần vào .git (hoặc dir chính nếu nó là repo trần) và thay đổi tệp HEAD để trỏ đến đúng đầu. Ví dụ: theo mặc định, nó luôn chứa 'refs: refs / heads / master', nhưng nếu bạn cần foo làm HEAD thay thế, chỉ cần chỉnh sửa tệp HEAD và thay đổi nội dung thành 'refs: refs / heads / foo'.


Tôi có quyền quản trị trên máy chủ Git và tôi cũng đã làm như vậy. Chúng tôi sử dụng Gitolite và tôi đã truy cập vào kho lưu trữ mà tôi đã tạo. Tên thư mục là myrepo.git. Nội dung của tệp HEAD trong thư mục nhất định đã được thay đổi từ ref: refs/heads/masterthành ref: refs/heads/mainline. Bây giờ, khi tôi cố gắng sao chép kho lưu trữ trên hộp cục bộ của mình, nó vẫn chỉ để làm chủ. Tôi chạy git clone ssh://gitolite@git.server/myrepolệnh. Bất kỳ ý tưởng cho hành vi như vậy?
Technext vào

Phiên bản máy chủ Git: git version 1.7.1& Phiên bản máy khách Git:git version 1.9.4.msysgit.2
Technext

5

Bạn có thể tạo một nhánh chính tách rời chỉ bằng các lệnh Git sứ:

git init
touch GO_AWAY
git add GO_AWAY
git commit -m "GO AWAY - this branch is detached from reality"

Cung cấp cho chúng ta một bậc thầy chi nhánh với một thông điệp thô lỗ (bạn có thể muốn trở thành lịch sự hơn). Bây giờ chúng ta tạo nhánh "thực" của mình (hãy gọi nó là thân để vinh danh SVN) và tách nó khỏi master :

git checkout -b trunk
git rm GO_AWAY
git commit --amend --allow-empty -m "initial commit on detached trunk"

Này, presto! gitk --all sẽ hiển thị cái chínhthân cây không có liên kết giữa chúng.

Điều "kỳ diệu" ở đây là --amend khiến git commit tạo ra một commit mới có cùng cha mẹ với HEAD hiện tại, sau đó làm cho HEAD trỏ đến nó. Nhưng HEAD hiện tại không có cha mẹ vì đó là cam kết ban đầu trong kho lưu trữ, vì vậy HEAD mới cũng không nhận được một, làm cho chúng tách rời khỏi nhau.

Cam kết HEAD cũ không bị git-gc xóa vì refs / heads / master vẫn trỏ đến nó.

Các --allow rỗng cờ chỉ cần thiết bởi vì chúng tôi cam kết một cây rỗng. Nếu có một số git add sau git rm thì nó sẽ không cần thiết.

Trên thực tế, bạn có thể tạo một nhánh tách rời bất kỳ lúc nào bằng cách phân nhánh cam kết ban đầu trong kho lưu trữ, xóa cây của nó, thêm cây đã tách của bạn, sau đó thực hiện git commit --amend .

Tôi biết điều này không trả lời câu hỏi về cách sửa đổi nhánh mặc định trên kho lưu trữ từ xa, nhưng nó đưa ra câu trả lời rõ ràng về cách tạo một nhánh tách rời.


1
Bạn có thể tạo một nhánh tách rời dễ dàng hơn bằng cách tìm nạp một nhánh không liên quan từ một kho khác và đặt tên cho nó. Ví dụ: git fetch git:user@example.com:foo remote-branch-name && git checkout -b detached-branch FETCH_HEADsẽ thêm chi nhánh mới detached-branchphù hợp với chi nhánh remote-branch-nameở xa git:user@example.com:foo. Tất nhiên, "điều khiển từ xa" có thể là một kho lưu trữ trong hệ thống tệp cục bộ mà bạn đã chuẩn bị trước đó.
Mikko Rantalainen

2

Đầu tiên, hãy tạo nhánh mới mà bạn muốn đặt làm mặc định, ví dụ:

$>git branch main

Tiếp theo, đẩy nhánh đó đến điểm gốc :

$>git push origin main

Bây giờ khi bạn đăng nhập vào tài khoản GitHub của mình, bạn có thể đi đến kho lưu trữ của mình và chọn Cài đặt> Chi nhánh mặc định và chọn " chính ".

Sau đó, nếu bạn chọn, bạn có thể xóa nhánh chính:

$>git push origin :master


Điểm mấu chốt cần hiểu là nếu nhà cung cấp dịch vụ lưu trữ của bạn (trong ví dụ này là GitHub) không cung cấp phương pháp sửa đổi nhánh mặc định thì bạn đã gặp may. Giao thức Git không cung cấp tính năng sửa đổi nhánh mặc định từ xa; bạn sẽ cần có khả năng chạy git symbolic-reftrên trình bao từ xa hoặc có thể sửa đổi tệp văn bản được gọi HEADtrong thư mục gốc của kho lưu trữ từ xa.
Mikko Rantalainen

2

Liên quan đến câu hỏi, tôi đã kết thúc ở đây khi tìm kiếm:

Làm cách nào để làm cho đại diện cục bộ nhận biết được nhánh mặc định đã thay đổi trên GitHub

Để đầy đủ, hãy thêm câu trả lời:

git remote set-head origin -a

0

Đối với những người sử dụng gitolite, gitolite hỗ trợ một lệnh được gọi là - đợi nó - symbolic-ref. Nó cho phép bạn chạy lệnh đó từ xa nếu bạn có quyền W (ghi) đối với repo.


-1

Đơn giản chỉ cần đăng nhập vào tài khoản GitHub của bạn và ở phía ngoài cùng bên phải trong menu điều hướng, chọn Cài đặt , trong tab Cài đặt, chọn Chi nhánh mặc định và quay lại trang chính của kho lưu trữ của bạn đã thực hiện thủ thuật cho tôi.


1
Mặc dù nó hiển thị nhánh mới làm mặc định trong giao diện GitHub, nhưng khi thực hiện sao chép git [repo], tôi không nhận được nhánh đó. tức là .git / HEAD chứa sai ref.
Joseph Sheedy
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.