Định nghĩa về hạ lưu và hạ lưu


902

Tôi đã bắt đầu chơi với Git và đã bắt gặp các thuật ngữ "ngược dòng" và "hạ lưu". Tôi đã nhìn thấy những điều này trước đây nhưng chưa bao giờ hiểu chúng đầy đủ. Những thuật ngữ này có ý nghĩa gì trong ngữ cảnh của SCM ( công cụ quản lý cấu hình phần mềm ) và mã nguồn?


13
Có hai bối cảnh khác nhau cho ngược dòng / hạ lưu trong git: điều khiển từ xa và thời gian / lịch sử. Ngược dòng / hạ lưu đối với điều khiển từ xa là, repo xuôi dòng sẽ được kéo từ repo ngược dòng (những thay đổi sẽ chảy xuôi một cách tự nhiên). Ngược dòng / hạ lưu liên quan đến thời gian / lịch sử có thể gây nhầm lẫn, bởi vì ngược dòng theo thời gian có nghĩa là hạ lưu trong lịch sử và ngược lại (thuật ngữ phả hệ hoạt động tốt hơn nhiều ở đây - cha mẹ / tổ tiên / con / con cháu).
charlesreid1


Câu trả lời:


703

Về mặt kiểm soát nguồn, bạn " hạ lưu " khi bạn sao chép (sao chép, thanh toán, v.v.) từ kho lưu trữ. Thông tin chảy "xuôi dòng" đến bạn.

Khi bạn thực hiện thay đổi, bạn thường muốn gửi chúng trở lại " ngược dòng " để họ thực hiện nó vào kho lưu trữ đó để mọi người lấy từ cùng một nguồn đang làm việc với tất cả các thay đổi giống nhau. Đây chủ yếu là một vấn đề xã hội về cách mọi người có thể điều phối công việc của họ chứ không phải là một yêu cầu kỹ thuật về kiểm soát nguồn. Bạn muốn nhận các thay đổi của mình vào dự án chính để không theo dõi các dòng phát triển khác nhau.

Đôi khi, bạn sẽ đọc về các trình quản lý gói hoặc phát hành (mọi người, không phải công cụ) nói về việc gửi các thay đổi cho "ngược dòng". Điều đó thường có nghĩa là họ phải điều chỉnh các nguồn ban đầu để có thể tạo một gói cho hệ thống của họ. Họ không muốn tiếp tục thực hiện những thay đổi đó, vì vậy nếu họ gửi chúng "ngược dòng" đến nguồn ban đầu, họ không cần phải xử lý vấn đề tương tự trong bản phát hành tiếp theo.


116
"Tải xuống" và "tải lên" là các động từ. "Thượng nguồn" và "hạ lưu" mô tả một vị trí tương đối.
brian d foy

2
Tôi muốn nói ngược dòng và xuôi dòng là tính từ
Crt

8
Chúng là tính từ khi chúng được sử dụng làm từ bổ nghĩa, nhưng những thuật ngữ đó thường được sử dụng làm danh từ.
brian d foy

2
Các từ @MycrofD có thể được sử dụng làm tính từ và danh từ tùy theo ngữ cảnh
reggaeg Ức

1
Đây chủ yếu là một vấn đề xã hội chứ không phải là một yêu cầu kỹ thuật . Vậy thì tại sao có một tùy chọn -unhư git push --set-upstream origin masternếu nó không phải là một yêu cầu kỹ thuật ? Chúng tôi có thể push -u originhoặc không push origin, vì vậy nó là một yêu cầu công nghệ. Nhưng sự khác biệt là gì?
Màu xanh lá cây

249

Khi bạn đọc trong git tagtrang man :

Một khía cạnh quan trọng của git là nó được phân phối và được phân phối phần lớn có nghĩa là không có "thượng nguồn" hoặc "hạ lưu" vốn có trong hệ thống.

, điều đó đơn giản có nghĩa là không có repo ngược dòng tuyệt đối hoặc repo xuôi dòng.
Những khái niệm này luôn tương đối giữa hai repos và phụ thuộc vào cách truyền dữ liệu:

Nếu "yourRepo" đã khai báo "otherRepo" là một điều khiển từ xa, thì :

  • bạn đang kéo từ thượng nguồn "otherRepo" ("otherRepo" là "ngược dòng từ bạn" và bạn là "hạ lưu cho otherRepo").
  • bạn đang đẩy lên thượng nguồn ("otherRepo" vẫn là "ngược dòng", nơi thông tin bây giờ quay trở lại).

Lưu ý "từ" và "cho": bạn không chỉ là "hạ lưu", bạn là "hạ lưu từ / cho ", do đó là khía cạnh tương đối.


Vòng xoắn DVCS (Hệ thống kiểm soát phiên bản phân tán) là: bạn không biết dòng dưới thực sự là gì, bên cạnh repo của chính bạn so với repos từ xa mà bạn đã khai báo.

  • bạn biết thượng nguồn là gì (các repos bạn đang kéo từ hoặc đẩy tới)
  • bạn không biết hạ lưu được làm từ gì (các repos khác kéo từ hoặc đẩy sang repo của bạn ).

Về cơ bản:

Về mặt " luồng dữ liệu ", repo của bạn ở dưới cùng ("xuôi dòng") của luồng đến từ repos ngược dòng ("kéo từ") và quay trở lại (cùng hoặc khác) repos ngược dòng ("đẩy tới" ).


Bạn có thể thấy một hình minh họa trong git-rebasetrang man với đoạn "THU HỒI TỪ UPSTREAM REBASE":

Điều đó có nghĩa là bạn đang kéo từ một repo "ngược dòng" nơi diễn ra một cuộc nổi loạn và bạn (repo "hạ lưu" bị mắc kẹt với hậu quả (rất nhiều cam kết trùng lặp, bởi vì nhánh bị ngược dòng tạo lại các cam kết của cùng một nhánh bạn có địa phương).

Điều đó là xấu bởi vì đối với một repo "ngược dòng", có thể có nhiều repos xuôi dòng (tức là repos kéo từ thượng nguồn, với nhánh bị từ chối), tất cả chúng đều có khả năng xử lý các cam kết trùng lặp.

Một lần nữa, với sự tương tự "luồng dữ liệu", trong một DVCS, một lệnh xấu "ngược dòng" có thể có " hiệu ứng gợn " xuôi dòng.


Lưu ý: điều này không giới hạn dữ liệu.
Nó cũng áp dụng cho các tham số , vì các lệnh git (như các lệnh "sứ") thường gọi các lệnh git khác trong nội bộ (các lệnh "ống nước"). Xem rev-parsetrang người đàn ông :

Nhiều lệnh git sành sứ lấy hỗn hợp các cờ (tức là các tham số bắt đầu bằng dấu gạch ngang ' -) và các tham số có nghĩa cho git rev-listlệnh bên dưới mà chúng sử dụng bên trong và cờ và tham số cho các lệnh khác mà chúng sử dụng xuôi dònggit rev-list . Lệnh này được sử dụng để phân biệt giữa chúng.


15
bạn kéo từ thượng nguồn, và bạn đẩy lên thượng nguồn. đẩy xuống hạ lưu nghe có vẻ rất sai đối với tôi
knittl

1
@knittl: bạn nói đúng. Tôi đã điều chỉnh lại câu trả lời của mình để minh họa rõ hơn vai trò của repo "ngược dòng" so với repo cục bộ (và "hạ lưu") của chính bạn.
VonC

85

Theo dõi ngược dòng (liên quan đến)

Thuật ngữ ngược dòng cũng có một số ý nghĩa rõ ràng khi nói đến bộ công cụ GIT, đặc biệt liên quan đến theo dõi

Ví dụ :

   $git rev-list --count --left-right "@{upstream}"...HEAD
   >4   12

sẽ in (giá trị được lưu trong bộ nhớ cache cuối cùng của) số lần xác nhận phía sau (bên trái) và phía trước (bên phải) của nhánh làm việc hiện tại của bạn, liên quan đến ( nếu có ) hiện đang theo dõi chi nhánh từ xa cho chi nhánh địa phương này. Nó sẽ in một thông báo lỗi khác:

    >error: No upstream branch found for ''
  • Như đã được nói, bạn có thể có bất kỳ số lượng điều khiển từ xa cho một kho lưu trữ địa phương, ví dụ, nếu bạn ngã ba một kho lưu trữ từ github, sau đó phát hành một 'yêu cầu kéo', bạn chắc chắn nhất có ít nhất hai: origin(repo chia hai bạn trên github) và upstream(repo trên github bạn đã rẽ nhánh). Đó chỉ là những tên có thể hoán đổi cho nhau, chỉ có url 'git @ ...' xác định chúng.

Bài .git/configđọc của bạn :

   [remote "origin"]
       fetch = +refs/heads/*:refs/remotes/origin/*
       url = git@github.com:myusername/reponame.git
   [remote "upstream"]
       fetch = +refs/heads/*:refs/remotes/upstream/*
       url = git@github.com:authorname/reponame.git
  • Mặt khác, ý nghĩa của @ {ngược dòng} đối với GIT là duy nhất:

đó là 'chi nhánh' (nếu có) trên 'điều khiển từ xa' , đang theo dõi 'chi nhánh hiện tại' trên 'kho lưu trữ cục bộ' của bạn .

Đó là nhánh bạn tìm nạp / kéo từ bất cứ khi nào bạn đưa ra một đơn giản git fetch/ git pull, không có đối số.

Giả sử muốn đặt nguồn gốc / chủ nhánh từ xa làm nhánh theo dõi cho nhánh chính cục bộ mà bạn đã kiểm tra. Chỉ cần phát hành:

   $ git branch --set-upstream  master origin/master
   > Branch master set up to track remote branch master from origin.

Điều này thêm 2 tham số trong .git/config:

   [branch "master"]
       remote = origin
       merge = refs/heads/master

bây giờ hãy thử (với điều kiện từ xa 'ngược dòng' có nhánh 'dev')

   $ git branch --set-upstream  master upstream/dev
   > Branch master set up to track remote branch dev from upstream.

.git/config bây giờ đọc:

   [branch "master"]
       remote = upstream
       merge = refs/heads/dev

git-push(1)Trang hướng dẫn :

   -u
   --set-upstream

Đối với mỗi nhánh được cập nhật hoặc được đẩy thành công, hãy thêm tham chiếu ngược dòng (theo dõi) , được sử dụng bởi git-pull (1) không cần đối số (1) và các lệnh khác. Để biết thêm thông tin, xem branch.<name>.mergetrong git-config (1).

git-config(1)Trang hướng dẫn :

   branch.<name>.merge

Xác định, cùng với branch.<name>.remote, nhánh ngược dòng cho nhánh đã cho. Nó báo cho git fetch / git pull / git rebase, nhánh nào sẽ hợp nhất và cũng có thể ảnh hưởng đến git đẩy (xem push.default). \ (...)

   branch.<name>.remote

Khi ở nhánh <name>, nó báo cho git fetch và git đẩy từ xa nào để tìm nạp từ / đẩy tới. Nó mặc định là nguồn gốc nếu không có điều khiển từ xa được cấu hình. nguồn gốc cũng được sử dụng nếu bạn không ở bất kỳ chi nhánh nào.

Ngược dòng và đẩy (Gotcha)

hãy xem git-config(1)trang hướng dẫn

   git config --global push.default upstream
   git config --global push.default tracking  (deprecated)

Điều này là để ngăn chặn những cú đẩy vô tình đến những nhánh mà bạn chưa sẵn sàng đẩy.


4
Trích từ git branch --helpnăm 2018:As this option had confusing syntax, it is no longer supported. Please use --track or --set-upstream-to instead.
zezoche

59

Đó là một chút thuật ngữ không chính thức.

Theo như Git, mọi kho lưu trữ khác chỉ là một điều khiển từ xa.

Nói chung, thượng nguồn là nơi bạn nhân bản từ (nguồn gốc). Hạ lưu là bất kỳ dự án nào tích hợp công việc của bạn với các công việc khác.

Các điều khoản không bị giới hạn trong kho Git.

Chẳng hạn, Ubuntu là một công cụ phái sinh Debian, vì vậy Debian là thượng nguồn cho Ubuntu.


51

Thượng nguồn gọi là có hại

Than ôi, có một cách sử dụng "ngược dòng" khác mà các câu trả lời khác ở đây không được đưa ra, cụ thể là đề cập đến mối quan hệ giữa cha mẹ và con cái trong một repo. Scott Chacon trong cuốn sách Git Pro đặc biệt thiên về điều này, và kết quả thật đáng tiếc. Đừng bắt chước cách nói này.

Ví dụ, ông nói về việc hợp nhất dẫn đến việc chuyển tiếp nhanh rằng điều này xảy ra vì

cam kết được chỉ ra bởi chi nhánh bạn đã sáp nhập trực tiếp ngược dòng của cam kết bạn đang thực hiện

Anh ta muốn nói rằng cam kết B là đứa con duy nhất của ... đứa con duy nhất của cam kết A, vì vậy để hợp nhất B vào A là đủ để di chuyển ref A đến điểm để cam kết B. Tại sao lại đi theo hướng này nên được gọi là "ngược dòng" chứ không phải "xuôi dòng", hoặc tại sao hình học của đồ thị đường thẳng thuần túy như vậy phải được mô tả "trực tiếp ngược dòng", hoàn toàn không rõ ràng và có thể tùy ý. (Trang nam giới git-mergethực hiện công việc tốt hơn nhiều để giải thích mối quan hệ này khi nói rằng "người đứng đầu chi nhánh hiện tại là tổ tiên của cam kết được đặt tên." Đó là điều mà Chacon nên nói.)

Thật vậy, bản thân Chacon dường như sử dụng "hạ lưu" sau này để có nghĩa chính xác điều tương tự, khi anh nói về việc viết lại tất cả các cam kết con của một cam kết đã bị xóa:

Bạn phải viết lại tất cả các cam kết xuôi dòng từ 6df76 để xóa hoàn toàn tệp này khỏi lịch sử Git của bạn

Về cơ bản, anh ta dường như không có bất kỳ ý tưởng rõ ràng nào về ý nghĩa của mình khi "ngược dòng" và "hạ lưu" khi đề cập đến lịch sử của các cam kết theo thời gian. Việc sử dụng này là không chính thức, sau đó, và không được khuyến khích, vì nó chỉ gây nhầm lẫn.

Một điều hoàn toàn rõ ràng là mọi cam kết (trừ một) đều có ít nhất một cha mẹ và cha mẹ của cha mẹ là tổ tiên; và theo hướng khác, cam kết có con và con cháu. Đó là thuật ngữ được chấp nhận và mô tả tính định hướng của biểu đồ một cách rõ ràng, vì vậy đó là cách để nói khi bạn muốn mô tả cách các cam kết liên quan đến nhau trong hình dạng biểu đồ của repo. Không sử dụng "ngược dòng" hoặc "xuôi dòng" một cách lỏng lẻo trong tình huống này.

[Ghi chú bổ sung: Tôi đã suy nghĩ về mối quan hệ giữa câu Chacon đầu tiên tôi trích dẫn ở trên và git-mergetrang người đàn ông, và điều đó xảy ra với tôi rằng cái trước có thể dựa trên sự hiểu lầm về cái sau. Trang con người tiếp tục mô tả một tình huống trong đó việc sử dụng "ngược dòng" là hợp pháp: chuyển tiếp nhanh thường xảy ra khi "bạn đang theo dõi một kho lưu trữ ngược dòng, bạn đã cam kết không có thay đổi cục bộ và bây giờ bạn muốn cập nhật lên một cái mới hơn sửa đổi ngược dòng. " Vì vậy, có lẽ Chacon đã sử dụng "thượng nguồn" bởi vì anh ta thấy nó ở đây trong trang người đàn ông. Nhưng trong trang man có một kho lưu trữ từ xa; không có kho lưu trữ từ xa trong ví dụ được trích dẫn của Chacon về chuyển tiếp nhanh, chỉ có một vài nhánh được tạo cục bộ.]


14
Trang man git-rebase cũng chịu sự quá tải này: cam kết được kiểm tra trước khi bắt đầu lại được gọi là "ngược dòng". Điều này cũng có thể ảnh hưởng đến việc sử dụng Chacon.
outis

@outis lạ - trong tài liệu git html, chi nhánh đã kiểm tra trước khi khởi động lại được gọi là <branch>.
Jesper Matthiesen

Điểm tốt. Sẽ là hữu ích để thu thập "thuật ngữ git" phổ biến ở đâu đó. Đặc biệt là cho người mới (hoặc ppl đóng góp cho git). Sẽ tiết kiệm cho tôi thời gian tốt để làm quen với từ ngữ của các trang git man.
SebNag

@SebNag một cái gì đó như thế này? linuxacademy.com/blog/linux/git-terms-explained
reggaeg Ức

1
Đến đây từ các git-rebasetài liệu bởi vì tôi hoàn toàn bối rối tại sao một giới thiệu cam kết sẽ được gọi là "thượng nguồn" ở đó (thực tế, tôi đã nghi ngờ chính mình khi tôi chưa thấy thuật ngữ này trước đây). Cảm ơn @outis & @matt vì đã dọn dẹp mọi thứ!
Borek Bernard

0

Nói chung;

  • thượng nguồn là về phía nguồn
  • hạ lưu là về phía chìm hoặc đích

Điều này áp dụng cho tất cả các hệ thống giống như cây, bao gồm các hệ thống kiểm soát nguồn.

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.