git: Chi nhánh của bạn đi trước X cam kết


379

Làm thế nào điều này thực sự xảy ra?

Hiện tại tôi đang làm việc trong một repo, vì vậy đây là quy trình làm việc của tôi:

  1. Thay đổi tập tin
  2. Cam kết
  3. Lặp lại 1-2 cho đến khi hài lòng
  4. Đẩy để làm chủ

Sau đó, khi tôi thực hiện, git statusnó cho tôi biết rằng chi nhánh của tôi đi trước X cam kết (có lẽ là cùng số lượng cam kết mà tôi đã thực hiện). Có phải bởi vì khi bạn đẩy mã, nó không thực sự cập nhật các tệp được lưu trong bộ nhớ cache cục bộ của bạn (trong các thư mục .git)? git pulldường như 'sửa' tin nhắn lạ này, nhưng tôi vẫn tò mò tại sao nó lại xảy ra, có lẽ tôi đang sử dụng git sai?


bao gồm những chi nhánh được in trong tin nhắn

Chi nhánh địa phương của tôi đi trước chủ

nơi nào bạn đẩy / kéo chi nhánh hiện tại

Tôi đang chuyển sang GitHub và kéo đến bất kỳ máy tính nào tôi đang làm việc tại thời điểm đó, bản sao cục bộ của tôi luôn được cập nhật đầy đủ vì tôi là người duy nhất làm việc trên nó.

nó không thực sự kiểm tra repo từ xa

Đó là những gì tôi nghĩ, tôi đoán rằng tôi sẽ đảm bảo sự hiểu biết của tôi về nó là chính xác.

bạn đang truyền thêm một số đối số cho nó?

Không phải cái mà tôi có thể thấy, có thể có một số cấu hình hài hước đang diễn ra ở phía cuối của tôi?

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

Làm thế nào bạn đang làm pushvà cài đặt cấu hình từ xa và chi nhánh của bạn là gì?
CB Bailey

2
Nó không thực sự kiểm tra repo từ xa, bạn cần thực hiện một git tìm nạp thông tin mới nhất về repo từ xa sau khi thực hiện việc đẩy, điều này sẽ cập nhật nhánh "từ xa" cục bộ mà nó sử dụng để theo dõi.
Sekhat

2
@Sekhat: Mặc dù git statuskhông kiểm tra kho lưu trữ từ xa git pull. Nếu bạn có một nhánh theo dõi cho một kho lưu trữ mà bạn đẩy tới, git pushsẽ cập nhật nhánh theo dõi cục bộ của bạn để phản ánh trạng thái mới của nhánh từ xa nếu việc đẩy của bạn thành công. Đây là lý do tại sao tôi hỏi về cấu hình của người hỏi vì nếu nó không xảy ra chính xác thì có thể có lỗi cấu hình.
CB Bailey

git status? có thật không? tôi git statuskhông bao giờ nói cho tôi biết phía trước chi nhánh của tôi là bao xa .. bạn có truyền thêm một số đối số cho nó không?
hasen

4
@hasen j: git statuskhông vào kho từ xa để kiểm tra xem nhánh từ xa đã được cập nhật chưa. Nó cho bạn biết bao xa về phía trước chi nhánh địa phương của bạn so với chi nhánh theo dõi từ xa được lưu trữ cục bộ của bạn . Vấn đề là một bình thường git push(cũng như tìm nạp và kéo) nên cập nhật nhánh theo dõi từ xa và đối với người hỏi thì điều này dường như không hoạt động. Để xem lý do tại sao chúng ta cần phải xem cả hình thức chính xác git pushđang được sử dụng và cấu hình của kho lưu trữ cục bộ nhưng vì người hỏi đã chấp nhận câu trả lời nên tôi không thể thấy điều này xảy ra ngay bây giờ.
CB Bailey

Câu trả lời:


508

Nếu bạn nhận được thông báo này sau khi thực hiện a git pull remote branch, hãy thử theo dõi nó với a git fetch. (Tùy chọn, chạy git fetch -pđể cắt tỉa các nhánh đã xóa khỏi repo)

Fetch dường như cập nhật đại diện cục bộ của chi nhánh từ xa, điều này không nhất thiết xảy ra khi bạn làm a git pull remote branch.


1
Bravo. Đó thực sự là vấn đề. Tôi bắt đầu bằng cách tạo một kho lưu trữ trên mã google. Sau đó, tôi đã nhân bản kho lưu trữ này trên máy tính xách tay của mình và tôi làm việc ở đó và đẩy các thay đổi, máy tính xách tay => code.google. Tôi đã từng nhận được thông báo này trên máy chủ của mình, nơi tôi đã tạo một bản sao của kho lưu trữ mã code.google và tôi đã sử dụng để lấy các thay đổi. Tôi nghĩ rằng tìm nạp là cần thiết để cập nhật cơ sở dữ liệu địa phương.
rjha94

2
Chúng tôi đã có cùng một vấn đề ở đây bởi vì một nhánh khác (A) đã chỉ ra cùng một cam kết của chủ. Kéo A và sau đó kéo chủ dẫn đến tình huống tương tự. Khi git kéo A, giao diện đã được cập nhật lên lần cuối, do đó, kéo chủ nó không có gì để thực sự kéo, vì vậy git đã không cập nhật cam kết cuối cùng của chủ và cảnh báo về việc "đi trước chủ".
Uber đến

8
Cảm ơn, mặc dù tôi đã nhận thấy một điều kỳ lạ. "git fetch origin master" không giúp ích gì, nhưng "git fetch origin" thì không. Tôi đang ở trong nhánh chính, vì vậy không chắc chắn "git fetch origin" sẽ làm điều gì đó khác biệt như thế nào trong bối cảnh.
Parag

2
@Parag xem stackoverflow.com/questions/26350876/, để được giải thích về sự khác biệt giữa hai lệnh đó và cách sửa đổi tệp cấu hình để thay đổi hành vi để git fetch nhánh từ xa cũng cập nhật ref git_status không báo cáo 'trước bởi'.
Nhà Anatort rùa

2
@Parag, cũng stackoverflow.com/questions/7365415/ Câu trả lời thảo luận về các chi tiết của ORIG_HEAD và FETCH_HEAD không đồng bộ hóa, gây ra cảnh báo trạng thái và có thể sửa tệp cấu hình.
Nhà Anatort rùa

138

Sử dụng

git pull --rebase

Tùy chọn --rebase có nghĩa là git sẽ chuyển cam kết cục bộ của bạn sang một bên, đồng bộ hóa với điều khiển từ xa và sau đó thử áp dụng các cam kết của bạn từ trạng thái mới.


3
Một cách thực sự tốt để ngăn chặn sự hợp nhất vô dụng và có một cây sạch hơn trong nguồn gốc!
Ghét

1
Tôi đã thử lệnh này, nhưng tôi vẫn gặp vấn đề tương tự ...$ git pull --rebase Current branch xyz is up to date. $ git status On branch xyz Your branch is ahead of 'origin/xyz' by 6 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean
bbh

4
Câu trả lời này là sai: Nếu bạn sử dụng nó mà không hiểu tình hình, bạn có khả năng gây rắc rối cho thời gian phía trước (viết lại lịch sử!). Nếu bạn hiểu tình hình, đây sẽ không phải là cách khắc phục. Vui lòng suy nghĩ trước khi bạn nhập khi sử dụng gitvà đừng bao giờ viết lại lịch sử!
cmaster - phục hồi monica

80

Sử dụng 3 lệnh đơn giản này

Bước 1 :git checkout <branch_name>

Bước 2 :git pull -s recursive -X theirs

Bước 3 :git reset --hard origin/<branch_name>

Thêm chi tiết: https://stackoverflow.com/a/39698570/2439715

Thưởng thức.


3
Đây là câu trả lời duy nhất thực sự khắc phục vấn đề cho tôi. Các lệnh trên đã hạ gục nó một cách kỳ lạ từ 12 đến 7 lần cam kết và điều này cuối cùng đã loại bỏ chúng
Ieuan

1
Tôi đồng tình về việc đây là điều duy nhất làm việc cho tôi. Đôi khi tôi tin rằng GIT bị rối loạn đa nhân cách.
ksed

11
Giống như @leuan, không có gì ngoài việc git reset --hard origin/masterxóa nó cho tôi.
Dave Land

Tương tự ở đây, đây là bước duy nhất phù hợp với tôi
Shard_MW

51

Tôi nghĩ rằng bạn đang đọc sai thông điệp - chi nhánh của bạn không đi trước master, đó master . Đó là trước origin/master, mà là một chi nhánh theo dõi từ xa ghi lại tình trạng của kho lưu trữ từ xa từ cuối cùng của bạn push, pullhoặc fetch. Nó cho bạn biết chính xác những gì bạn đã làm; bạn đã đi trước điều khiển từ xa và nó nhắc nhở bạn phải đẩy.


22
Đây thực sự là sau khi tôi đẩy. Tôi đã phải kéo (hoặc có thể tìm nạp?) Để có được nó để không có tin nhắn đó.
SeanJA

26

Ai đó nói rằng bạn có thể đang đọc sai tin nhắn của bạn, bạn thì không. Vấn đề này thực sự phải làm với <project>/.git/configtập tin của bạn . Trong đó sẽ có một phần tương tự như thế này:

[remote "origin"]
    url = <url>
    fetch = +refs/heads/*:refs/remotes/origin/*

Nếu bạn xóa dòng tìm nạp khỏi tệp .git / config của dự án, bạn sẽ dừng "Chi nhánh của bạn đi trước 'origin / master' bằng các Ncam kết." phiền toái từ xảy ra.

Hoặc vì vậy tôi hy vọng. :)


Tôi sẽ kiểm tra xem lần sau tôi thấy ahead by x commitstin nhắn. Tôi đã không thấy tin nhắn trong một thời gian.
SeanJA

Tôi đã không thấy tin nhắn trong một thời gian. Tôi nghĩ rằng đó là vì tôi đã bắt đầu tạo repo git cục bộ, sau đó đẩy nó sang repo từ xa thay vì cách khác ...
SeanJA

Tôi đã thử điều này, nhưng nó làm cho eGit trong Eclipse bắt đầu xuất hiện với "lỗi nội bộ" khi tôi cố gắng cam kết. Git dường như làm việc tốt, mặc dù.
dùng4815162342

18
Dòng đó làm gì? và tôi đang bỏ lỡ điều gì bằng cách loại bỏ nó? (ngoài sự khó chịu)
John Mee

1
Điều này đã làm việc, nhưng nó giống như việc khắc phục lỗi. Thêm dòng trở lại và bạn sẽ bắt đầu nhận được cảnh báo một lần nữa.
Krishna Pandey

15

Tôi đã có vấn đề này trên máy chủ sân khấu của tôi, nơi tôi chỉ kéo. Và thiết lập lại cứng đã giúp tôi làm sạch ĐẦU giống như điều khiển từ xa.

git reset --hard origin/master

Vì vậy, bây giờ tôi có một lần nữa:

On branch master
Your branch is up-to-date with 'origin/master'.

Lần đầu tiên tôi thử mà không có cờ --hard và nó đã hoạt động!
kroiz

12

Điều này làm việc cho tôi

git reset --hard origin/master

Đầu ra phải như thế nào

On branch dev HEAD is now at ae1xc41z Last commit message


11

Trong trường hợp của tôi, đó là vì tôi đã chuyển sang sử dụng chính

 git checkout -B master

Chỉ cần kéo phiên bản mới của nó thay vì

 git checkout master

Lệnh đầu tiên đặt lại đầu của chủ thành các cam kết mới nhất của tôi

Tôi đã sử dụng

git reset --hard origin/master

Để khắc phục điều đó


9

Tôi đã xem qua mọi giải pháp trên trang này và may mắn thay @ anatolii-pazhyn đã nhận xét vì giải pháp của anh ấy là giải pháp hiệu quả. Thật không may, tôi không có đủ danh tiếng để nâng đỡ anh ta, nhưng tôi khuyên bạn nên thử giải pháp của anh ta trước:

git reset --hard origin/master

Mà đã cho tôi:

HEAD is now at 900000b Comment from my last git commit here

Tôi cũng đề nghị:

git rev-list origin..HEAD
# to see if the local repository is ahead, push needed

git rev-list HEAD..origin
# to see if the local repository is behind, pull needed

Bạn cũng có thể dùng:

git rev-list --count --left-right origin/master...HEAD
# if you have numbers for both, then the two repositories have diverged

May mắn nhất


4

Tôi gặp vấn đề tương tự trên máy Windows. Khi tôi chạy một git pull origin masterlệnh, tôi sẽ nhận được cảnh báo "đi trước 'gốc / chủ" của X cam kết ". Tôi thấy rằng nếu tôi thay vào đó chạy git pull originvà KHÔNG chỉ định chi nhánh, thì tôi sẽ không còn nhận được cảnh báo nữa.


Tôi tin rằng điều này có hiệu quả git fetchđằng sau hậu trường.
Brian Peterson

"git fetch" không giải quyết được vấn đề của tôi, điều này đã làm. Tôi nhận được danh sách các nhánh mới được thêm vào và thông báo này "Bạn đã yêu cầu kéo từ 'thượng nguồn' từ xa, nhưng không chỉ định một nhánh. Vì đây không phải là điều khiển từ xa được cấu hình mặc định cho nhánh hiện tại của bạn, bạn phải chỉ định một nhánh trên lệnh hàng." và lệnh "git status" tiếp theo không hiển thị cảnh báo.
Krishna Pandey

2

Nó chỉ nhắc nhở bạn về sự khác biệt giữa nhánh hiện tại và nhánh thực hiện theo dõi hiện tại. Vui lòng cung cấp thêm thông tin, bao gồm chi nhánh nào được in trong tin nhắn và nơi bạn đẩy / kéo chi nhánh hiện tại.


2

Mặc dù câu hỏi này hơi cũ ... Tôi đã ở trong một tình huống tương tự và câu trả lời của tôi ở đây đã giúp tôi khắc phục một vấn đề tương tự tôi gặp phải

Thử đầu tiên với push -f hoặc tùy chọn lực lượng

Nếu điều đó không hoạt động thì có thể (như trong trường hợp của tôi) các kho lưu trữ từ xa (hay đúng hơn là các tham chiếu đến các kho lưu trữ từ xa hiển thị trên git remote -v ) có thể không được cập nhật.

Kết quả ở trên là lần đẩy của bạn được đồng bộ hóa cục bộ / chi nhánh của bạn với điều khiển từ xa / chi nhánh của bạn, tuy nhiên, bộ đệm trong repo cục bộ của bạn vẫn hiển thị cam kết trước đó (của cục bộ / chi nhánh ... chỉ cung cấp một lần cam kết duy nhất) là CHÍNH.

Để xác nhận bản sao trên, repo ở một vị trí khác và thử so sánh ĐẦU / cục bộ và đầu từ xa / nhánh. Nếu cả hai đều giống nhau thì có lẽ bạn đang phải đối mặt với vấn đề tôi đã làm.

Giải pháp:

$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)
$ git remote add origin git://github.com/pjhyett/hw.git
$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)
origin  git://github.com/pjhyett/hw.git (fetch)
origin  git://github.com/pjhyett/hw.git (push)
$ git remote rm origin
$ git remote -v
github  git@github.com:schacon/hw.git (fetch)
github  git@github.com:schacon/hw.git (push)

Bây giờ làm push -fnhư sau

git push -f github master ### Lưu ý lệnh của bạn không origincòn nữa!

Làm git pullngay bây giờ git pull github master

khi git statusnhận

# On branch master

nothing to commit (working directory clean)

Tôi hy vọng điều này hữu ích cho ai đó vì số lượt xem quá cao nên việc tìm kiếm lỗi này hầu như luôn liệt kê chủ đề này lên đầu

Cũng tham khảo gitref để biết chi tiết


2

Tôi thực sự đã có điều này xảy ra khi tôi đang thực hiện chuyển đổi / thanh toán với TortiseGIT.

Vấn đề của tôi là tôi đã tạo ra chi nhánh dựa trên một chi nhánh địa phương khác. Nó tạo ra một mục "hợp nhất" trong /.git/configđó trông giống như thế này:

[branch "web"]
    merge = refs/heads/develop
    remote = gitserver

Bất cứ khi nào tôi chuyển sang chi nhánh "web", nó nói với tôi rằng tôi đã hơn 100 lần cam kết trước khi phát triển. Vâng, tôi đã không còn cam kết phát triển vì vậy đó là sự thật. Tôi đã có thể chỉ cần loại bỏ mục này và nó dường như hoạt động như mong đợi. Đó là theo dõi đúng với ref từ xa thay vì phàn nàn về việc đứng sau nhánh phát triển.

Như Vikram đã nói, luồng Stack Overflow này là kết quả hàng đầu của Google khi tìm kiếm vấn đề này vì vậy tôi nghĩ tôi sẽ chia sẻ tình huống và giải pháp của mình.


2

Tôi muốn nhắc lại điều tương tự như được đề cập bởi @Marian Zburlia ở trên. Nó làm việc cho tôi và sẽ đề nghị tương tự cho những người khác.

git pull origin develop

nên được theo sau $ git pull --rebase.

Điều này sẽ loại bỏ các ý kiến ​​sắp tới $ git statussau khi kéo mới nhất.


2

git fetch sẽ giải quyết điều này cho bạn

Nếu sự hiểu biết của tôi là chính xác, cục bộ (bộ nhớ cache) origin/mastercủa bạn đã hết hạn. Lệnh này sẽ cập nhật trạng thái kho lưu trữ từ máy chủ.


1
Vui lòng thêm một số mô tả
Mathews Sunny

2

Sau đó, khi tôi thực hiện một trạng thái git, nó cho tôi biết rằng chi nhánh của tôi đi trước X cam kết (có lẽ là cùng số lượng cam kết mà tôi đã thực hiện ).

Kinh nghiệm của tôi là trong một môi trường nhóm với nhiều chi nhánh. Chúng tôi làm việc trong các nhánh tính năng của riêng mình (trong các bản sao địa phương) và đó là một trong những chương git statustrình cho thấy tôi là 11 người đi trước. Giả định làm việc của tôi, giống như tác giả của câu hỏi, là +11 là từ các cam kết của riêng tôi .

Hóa ra tôi đã thay đổi từ developnhánh chung sang nhánh tính năng của mình nhiều tuần trước - nhưng quên mất! Khi tôi xem lại chi nhánh tính năng địa phương của mình ngày hôm nay và git pull origin developcon số đã tăng lên +41 cam kết phía trước. Nhiều công việc đã được thực hiện developvà vì vậy chi nhánh tính năng cục bộ của tôi thậm chí còn đi trước chi nhánh tính năng trênorigin kho lưu trữ.

Vì vậy, nếu bạn nhận được thông báo này, hãy nghĩ lại bất kỳ thao tác kéo / sáp nhập nào bạn có thể đã thực hiện từ các chi nhánh khác (của chính bạn hoặc của người khác) mà bạn có quyền truy cập. Thông báo chỉ báo hiệu bạn cần git pushnhững pulled thay đổi trở lại originrepo ('nhánh theo dõi') từ repo cục bộ của bạn để mọi thứ được đồng bộ hóa.


1

Các câu trả lời gợi ý git pullhoặc git fetchlà chính xác.
Thông báo được tạo khi git statusthấy sự khác biệt giữa .git/FETCH_HEAD.git/refs/remotes/<repository>/<branch>(ví dụ .git/refs/remotes/origin/master).

Tệp sau ghi lại CHÍNH từ lần tìm nạp cuối cùng (đối với kho lưu trữ / nhánh). Thực hiện git fetchcập nhật cả hai tập tin lên CHÍNH hiện tại của chi nhánh.
Tất nhiên, nếu không có gì để tìm nạp (vì kho lưu trữ cục bộ đã được cập nhật) thì .git/FETCH_HEADsẽ không thay đổi.


Điều này dường như không phải là trường hợp đối với tôi: .git/FETCH_HEADchứa 9f7336c873ccffc772168bf49807e23ff74014d3 branch 'master' of URL.git/refs/remotes/origin/masterchứa 9f7336c873ccffc772168bf49807e23ff74014d3, nhưng tôi vẫn nhận được tin nhắn và git pullcũng không git fetchgiải quyết được
Davide

0

Nếu bạn nhận được thông báo này sau khi thực hiện một cam kết để hủy theo dõi tệp trong nhánh, hãy thử thực hiện một số thay đổi trong bất kỳ tệp nào và thực hiện cam kết. Rõ ràng bạn không thể thực hiện một cam kết duy nhất chỉ bao gồm việc không theo dõi tệp được theo dõi trước đó. Cuối cùng, bài đăng này đã giúp tôi giải quyết toàn bộ vấn đề https://help.github.com/articles/removing-files-from-a-reposeective-s-history/ . Tôi chỉ phải xóa tập tin khỏi lịch sử kho lưu trữ.

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.