คำจำกัดความของ“ ดาวน์สตรีม” และ“ อัพสตรีม”


901

ฉันเริ่มเล่นกับ Git และเจอกับคำว่า "upstream" และ "downstream" ฉันเคยเห็นสิ่งเหล่านี้มาก่อน แต่ไม่เคยเข้าใจพวกเขาอย่างเต็มที่ คำเหล่านี้มีความหมายอย่างไรในบริบทของ SCM ( เครื่องมือการจัดการการกำหนดค่าซอฟต์แวร์ ) และซอร์สโค้ด


13
มีบริบทที่แตกต่างกันสองประการสำหรับอัปสตรีม / ดาวน์สตรีมในคอมไพล์: รีโมตและเวลา / ประวัติ อัพสตรีม / ดาวน์สตรีมด้วยความเคารพต่อรีโมตคือ repo ดาวน์สตรีมจะถูกดึงจาก repo อัปสตรีม (การเปลี่ยนแปลงจะไหลดาวน์สตรีมตามธรรมชาติ) อัปสตรีม / ดาวน์สตรีมด้วยความเคารพต่อเวลา / ประวัติอาจทำให้เกิดความสับสนเพราะอัพสตรีมในเวลาหมายถึงดาวน์สตรีมในประวัติศาสตร์และในทางกลับกัน
charlesreid1

6
ที่เกี่ยวข้อง: 'ต้นน้ำ' หมายถึงอะไร ที่ OS
kenorb

คำตอบ:


703

ในแง่ของการควบคุมแหล่งที่มาคุณกำลัง " ดาวน์สตรีม " เมื่อคุณคัดลอก (โคลน, เช็คเอาต์และอื่น ๆ ) จากที่เก็บ ข้อมูลไหล "ลง" ถึงคุณ

เมื่อคุณทำการเปลี่ยนแปลงคุณมักจะต้องการส่งกลับ " อัปสตรีม " เพื่อให้พวกเขาลงในพื้นที่เก็บข้อมูลนั้นเพื่อให้ทุกคนที่ดึงจากแหล่งเดียวกันนั้นทำงานกับการเปลี่ยนแปลงเดียวกันทั้งหมด นี่เป็นปัญหาทางสังคมส่วนใหญ่ว่าทุกคนสามารถประสานงานของพวกเขาได้มากกว่าความต้องการด้านเทคนิคของการควบคุมแหล่งที่มา คุณต้องการรับการเปลี่ยนแปลงในโครงการหลักดังนั้นคุณจึงไม่ได้ติดตามสายการพัฒนาที่หลากหลาย

บางครั้งคุณจะอ่านเกี่ยวกับแพ็คเกจหรือผู้จัดการประจำ (คนไม่ใช่เครื่องมือ) พูดคุยเกี่ยวกับการส่งการเปลี่ยนแปลงเพื่อ "อัปสตรีม" นั่นหมายถึงพวกเขาต้องปรับแหล่งต้นฉบับเพื่อให้สามารถสร้างแพ็คเกจสำหรับระบบของพวกเขาได้ พวกเขาไม่ต้องการทำการเปลี่ยนแปลงเหล่านั้นดังนั้นหากพวกเขาส่ง "อัปสตรีม" ไปยังแหล่งดั้งเดิมพวกเขาไม่ควรต้องจัดการกับปัญหาเดียวกันในรีลีสถัดไป


116
"ดาวน์โหลด" และ "อัปโหลด" เป็นคำกริยา "อัปสตรีม" และ "ดาวน์สตรีม" อธิบายตำแหน่งสัมพัทธ์
brian d foy

2
ฉันจะบอกว่าต้นน้ำและปลายน้ำเป็นคำคุณศัพท์
Crt

8
มันเป็นคำคุณศัพท์เมื่อใช้เป็นตัวดัดแปลง แต่คำเหล่านั้นมักใช้เป็นคำนาม
brian d foy

2
@MycrofD คำสามารถใช้เป็นคำคุณศัพท์และคำนามขึ้นอยู่กับบริบท
reggaeguitar

1
นี้เป็นส่วนใหญ่เป็นปัญหาสังคมมากกว่าความต้องการทางเทคนิค แล้วทำไมมีตัวเลือก-uเช่นgit push --set-upstream origin masterถ้ามันไม่ได้เป็นความต้องการทางเทคนิค ? เราสามารถpush -u originหรือไม่ใช้push originดังนั้นจึงเป็นความต้องการด้านเทคโนโลยี แต่ความแตกต่างคืออะไร
กรีน

249

เมื่อคุณอ่านในgit tagman page :

สิ่งสำคัญอย่างหนึ่งของ git คือการแจกจ่ายและการกระจายส่วนใหญ่หมายความว่าไม่มี "upstream" หรือ "downstream" ในระบบ

ที่เพียงแค่หมายความว่าไม่มีแน่นอน repo ต้นน้ำหรือปลายน้ำ repo
แนวคิดเหล่านั้นสัมพันธ์กันเสมอระหว่างสอง repos และขึ้นอยู่กับการไหลของข้อมูล:

หาก "yourRepo" ได้ประกาศว่า "otherRepo" เป็นรีโมตให้ทำดังนี้:

  • คุณกำลังดึงจากอัปสตรีม "otherRepo" ("otherRepo" คือ "อัปสตรีมจากคุณ" และคุณเป็น "ดาวน์สตรีมสำหรับ otherRepo")
  • คุณกำลังผลักดันให้ upstream ("otherRepo" ยังคงเป็น "upstream" ซึ่งตอนนี้ข้อมูลกลับไปที่)

หมายเหตุ "จาก" และ "สำหรับ": คุณไม่ได้เป็นเพียง "ดาวน์สตรีม" แต่เป็น "ดาวน์สตรีมจาก / สำหรับ " ดังนั้นจึงเป็นแง่มุมที่สัมพันธ์กัน


การบิด DVCS (ระบบการควบคุมเวอร์ชันแจกจ่าย) คือ: คุณไม่รู้ว่าจริงๆแล้วคือ downstream ข้าง repo ของคุณเองเมื่อเทียบกับ repos ระยะไกลที่คุณประกาศ

  • คุณรู้ว่า upstream คืออะไร (repos ที่คุณกำลังดึงหรือดันไป)
  • คุณไม่ทราบว่าผลิตภัณฑ์ดาวน์สตรีมทำอะไร (repos อื่นดึงจากหรือผลักดันไปยังrepo ของคุณ )

โดยทั่วไป:

ในแง่ของ " การไหลของข้อมูล " repo ของคุณอยู่ที่ด้านล่าง ("downstream") ของการไหลที่มาจาก repos upstream ("pull from") และกลับไปที่ repos upstream (เดียวกันหรืออื่น ๆ ) ("push to" )


คุณสามารถดูภาพประกอบในgit-rebaseman pageพร้อมกับย่อหน้า "การกู้คืนจากการอัปเดตจาก UPSTREAM":

หมายความว่าคุณกำลังดึงจาก repo "อัปสตรีม" ที่รีบูตเกิดขึ้นและคุณ (repo "ดาวน์สตรีม") ติดอยู่กับผลลัพธ์ (ซ้ำจำนวนมากคอมมิชชันเนื่องจากสาขาที่รีบูท upstream up สร้างคอมมิชชันของสาขาเดียวกันกับคุณ มีในท้องถิ่น)

นั่นเป็นสิ่งที่ไม่ดีเพราะสำหรับ repo "upstream" หนึ่งอาจมีrepos ดาวน์สตรีมจำนวนมาก (เช่น repos ที่ดึงจาก upstream ด้วย repased branch) พวกเขาทั้งหมดมีศักยภาพที่จะจัดการกับคอมมิชชันที่ซ้ำกัน

อีกครั้งเมื่อมีการเปรียบเทียบ "การไหลของข้อมูล" ใน DVCS คำสั่งที่ไม่ถูกต้องคำสั่งเดียว "อัปสตรีม" สามารถมี " ผลกระเพื่อม " ได้


หมายเหตุ: สิ่งนี้ไม่ จำกัด เฉพาะข้อมูล
นอกจากนี้ยังใช้กับพารามิเตอร์เช่นคำสั่ง git (เช่นคำสั่ง "Porcelain") มักจะเรียกคำสั่ง git อื่น ๆ ภายใน (คำสั่ง "plumbing") ดูrev-parseหน้าคน :

คำสั่งคอมไพล์ porcelainish หลายคนใช้ส่วนผสมของธง (เช่นพารามิเตอร์ที่ขึ้นต้นด้วยเส้นประ ' -') และพารามิเตอร์หมายสำหรับอ้างอิงgit rev-listคำสั่งพวกเขาใช้ภายในและธงและพารามิเตอร์สำหรับคำสั่งอื่น ๆ git rev-listที่พวกเขาใช้น้ำจาก คำสั่งนี้ใช้เพื่อแยกความแตกต่างระหว่างพวกเขา


15
คุณดึงจากอัปสตรีมและคุณดันไปที่อัพสตรีม การกดลงไปที่ปลายน้ำฟังดูผิดมากสำหรับฉัน
knittl

1
@ knittl: ถูกต้อง ฉันได้คำตอบของฉันใหม่เพื่อแสดงบทบาทของ repo "upstream" ที่ดีขึ้นเมื่อเทียบกับ repo ในท้องถิ่นของคุณ (และ "downstream")
VonC

85

การติดตามอัปสตรีม (ตามที่เกี่ยวข้องกับ)

คำต้นน้ำยังมีความหมายที่ชัดเจนบางอย่างที่มากับชุดเครื่องมือ GIT โดยเฉพาะอย่างยิ่งที่เกี่ยวข้องกับการติดตาม

ตัวอย่างเช่น :

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

จะพิมพ์ (มูลค่าแคชสุดท้ายของ) จำนวนการกระทำที่อยู่เบื้องหลัง (ซ้าย) และข้างหน้า (ขวา) ของสาขาการทำงานปัจจุบันของคุณเทียบกับ ( ถ้ามี ) ในปัจจุบันการติดตามสาขาระยะไกลสำหรับสาขาท้องถิ่นนี้ มันจะพิมพ์ข้อความผิดพลาดเป็นอย่างอื่น:

    >error: No upstream branch found for ''
  • ตามที่ได้กล่าวไปแล้วคุณอาจมีรีโมตจำนวนเท่าใดก็ได้สำหรับที่เก็บโลคัลหนึ่งตัวอย่างเช่นถ้าคุณแยกที่เก็บจาก github จากนั้นเรียก 'ดึงคำขอ' คุณมีอย่างน้อยสอง: origin(repo ที่แยกจากกันบน gitHub) และupstream(repo บน GitHub คุณแยกจาก) เหล่านี้เป็นเพียงชื่อที่ใช้แทนกันได้เฉพาะ 'git @ ... ' url เท่านั้นที่ระบุได้

การ.git/configอ่านของคุณ:

   [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
  • ในทางกลับกันความหมายของ@ {upstream}สำหรับ GIT นั้นไม่เหมือนใคร:

มันคือ'สาขา' (ถ้ามี) ใน'รีโมตที่กล่าวว่า'ซึ่งกำลังติดตาม'สาขาปัจจุบัน'ใน'คลังเก็บในพื้นที่ของคุณ'

เป็นสาขาที่คุณดึง / ดึงจากเมื่อใดก็ตามที่คุณออกgit fetch/ git pullโดยไม่มีข้อโต้แย้ง

สมมติว่าต้องการตั้งค่าที่มาสาขาย่อย / ต้นแบบจากระยะไกลให้เป็นสาขาการติดตามสำหรับสาขาต้นแบบท้องถิ่นที่คุณเช็คเอาต์ เพียงแค่ปัญหา:

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

สิ่งนี้จะเพิ่ม 2 พารามิเตอร์ใน.git/config:

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

ตอนนี้ลอง (ให้ระยะไกล 'upstream' มีสาขา 'dev')

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

.git/config ตอนนี้อ่าน:

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

git-push(1)หน้าคู่มือ :

   -u
   --set-upstream

สำหรับทุกสาขาที่เป็นข้อมูลล่าสุดหรือถูกผลักสำเร็จให้เพิ่มการอ้างอิงupstream (การติดตาม) ที่ใช้โดยคำสั่ง git-pull (1) และอาร์กิวเมนต์อื่นที่ไม่ใช้อาร์กิวเมนต์ สำหรับข้อมูลเพิ่มเติมดูbranch.<name>.mergeใน git-config (1)

git-config(1)หน้าคู่มือ :

   branch.<name>.merge

กำหนดร่วมกับbranch.<name>.remoteที่ต้นน้ำสาขาสาขาที่กำหนด มันบอก git fetch / git pull / git rebase ว่าจะรวมสาขาใดบ้างและสามารถส่งผลต่อ git push ได้ (ดู push.default) \ (... )

   branch.<name>.remote

เมื่ออยู่ใน branch <name> มันจะบอก git fetch และ git push ซึ่งรีโมตที่จะดึงข้อมูลจาก / push to มันเป็นค่าเริ่มต้นที่จะกำเนิดหากไม่มีการกำหนดค่าระยะไกล ต้นกำเนิดยังใช้ถ้าคุณไม่ได้อยู่ในสาขาใด ๆ

ต้นน้ำและดัน (Gotcha)

ลองดูที่git-config(1)หน้าคู่มือ

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

นี่คือเพื่อป้องกันการกดไปยังกิ่งที่ไม่ได้ตั้งใจซึ่งคุณยังไม่พร้อมที่จะผลัก


4
ส่วนที่ตัดตอนมาจากgit branch --helpณ วันที่ 2018:As this option had confusing syntax, it is no longer supported. Please use --track or --set-upstream-to instead.
zezollo

59

นั่นเป็นคำศัพท์ที่ไม่เป็นทางการ

เท่าที่ Git เกี่ยวข้องพื้นที่เก็บข้อมูลอื่น ๆ ทั้งหมดก็แค่รีโมตเท่านั้น

โดยทั่วไปการอัปสตรีมเป็นที่ที่คุณลอกแบบ (ต้นกำเนิด) ดาวน์สตรีมคือโครงการใด ๆ ที่รวมงานของคุณเข้ากับงานอื่น

ข้อกำหนดไม่ได้ จำกัด อยู่ที่ที่เก็บ Git

ตัวอย่างเช่น Ubuntu เป็นอนุพันธ์ของเดเบียนดังนั้น Debian จึงเป็นอัพสตรีมสำหรับ Ubuntu


51

ต้นน้ำเรียกว่าเป็นอันตราย

นั่นคืออนิจจาการใช้ "ต้นน้ำ" อีกครั้งที่คำตอบอื่น ๆ ที่นี่ไม่ได้รับคือกล่าวถึงความสัมพันธ์พ่อแม่และลูกของคอมมิชชันภายใน repo Scott Chacon ในหนังสือ Pro Gitโดยเฉพาะอย่างยิ่งมีแนวโน้มนี้และผลลัพธ์จะโชคร้าย อย่าเลียนแบบวิธีการพูดนี้

ตัวอย่างเช่นเขาพูดถึงการรวมที่เกิดขึ้นอย่างรวดเร็วว่าสิ่งนี้เกิดขึ้นเพราะ

คอมมิชชันที่ชี้ไปตามสาขาที่คุณรวมเข้าไปนั้นเป็นข้อมูลต้นน้ำโดยตรงของการส่งข้อมูลที่คุณกำลังดำเนินอยู่

เขาต้องการที่จะบอกว่าการกระทำ B เป็นลูกคนเดียวของลูกคนเดียวของ ... ของลูกคนเดียวของการกระทำดังนั้นเพื่อรวม B เป็น A มันก็เพียงพอที่จะย้ายผู้อ้างอิงไปยังจุดที่จะกระทำ B. ทำไมทิศทางนี้ ควรเรียกว่า "อัปสตรีม" แทนที่จะเป็น "ดาวน์สตรีม" หรือทำไมรูปทรงเรขาคณิตของกราฟเส้นตรงที่บริสุทธิ์เช่นนี้ควรจะอธิบายว่า "อัปสตรีมโดยตรง" นั้นไม่มีความชัดเจนอย่างสมบูรณ์และอาจไม่มีเหตุผล (หน้าคนgit-mergeที่ทำงานได้ดีกว่าการอธิบายความสัมพันธ์นี้เมื่อกล่าวว่า "หัวหน้าสาขาปัจจุบันเป็นบรรพบุรุษของการกระทำที่มีชื่อ" นั่นคือสิ่งที่ Chacon ควรพูด)

อันที่จริง Chacon ตัวเองดูเหมือนจะใช้ "ดาวน์สตรีม" ในภายหลังเพื่อหมายถึงสิ่งเดียวกันอย่างแน่นอนเมื่อเขาพูดถึงการเขียนใหม่เด็กทุกคนกระทำการกระทำที่ถูกลบ:

คุณต้องเขียนดาวน์สตรีมทั้งหมดที่กระทำต่อเนื่องจาก 6df76 เพื่อลบไฟล์นี้อย่างสมบูรณ์จากประวัติ Git ของคุณ

โดยทั่วไปดูเหมือนว่าเขาจะไม่ได้มีความคิดที่ชัดเจนใด ๆ สิ่งที่เขาหมายถึงโดย "ต้นน้ำ" และ "ปลายน้ำ" เมื่อพูดถึงประวัติศาสตร์ของความมุ่งมั่นในช่วงเวลา การใช้งานนี้เป็นทางการแล้วและไม่ควรได้รับการสนับสนุนเนื่องจากเป็นเพียงความสับสน

เป็นที่ชัดเจนอย่างสมบูรณ์ว่าทุกการกระทำ (ยกเว้นหนึ่ง) มีอย่างน้อยหนึ่งผู้ปกครองและผู้ปกครองของพ่อแม่เป็นบรรพบุรุษ และในอีกทางหนึ่งมีลูกและลูกหลาน นั่นเป็นคำศัพท์ที่ได้รับการยอมรับและอธิบายทิศทางของกราฟอย่างไม่น่าสงสัยดังนั้นจึงเป็นวิธีที่จะพูดเมื่อคุณต้องการอธิบายถึงความสัมพันธ์ที่มีต่อกันภายในเรขาคณิตกราฟของ repo อย่าใช้ "upstream" หรือ "downstream" อย่างหลวม ๆ ในสถานการณ์นี้

[หมายเหตุเพิ่มเติม: ฉันกำลังคิดถึงความสัมพันธ์ระหว่างประโยค Chacon แรกที่ฉันอ้างถึงข้างต้นและgit-mergeหน้าคนและมันเกิดขึ้นกับฉันว่าอดีตอาจขึ้นอยู่กับความเข้าใจผิดของหลัง หน้า man จะอธิบายสถานการณ์ที่การใช้ "upstream" นั้นถูกต้องตามกฎหมาย: การส่งต่ออย่างรวดเร็วมักเกิดขึ้นเมื่อ "คุณกำลังติดตามพื้นที่เก็บข้อมูล upstream คุณไม่ได้ทำการเปลี่ยนแปลงในเครื่องและตอนนี้คุณต้องการอัปเดตใหม่ การแก้ไขต้นน้ำ " ดังนั้น Chacon อาจใช้ "upstream" เพราะเขาเห็นที่นี่ในหน้าคน แต่ในหน้าคนมีที่เก็บระยะไกล; ไม่มีที่เก็บข้อมูลระยะไกลในตัวอย่างที่อ้างถึงของ Chacon เกี่ยวกับการส่งต่ออย่างรวดเร็วเพียงไม่กี่สาขาที่สร้างขึ้นภายในเครื่อง]


14
หน้าคน git-rebase ยังทนทุกข์ทรมานจากการบรรทุกเกินพิกัดนี้: การกระทำที่มีการตรวจสอบก่อนที่จะมีการเรียกว่าการรีบูต "upstream" ซึ่งอาจส่งผลต่อการใช้งานของ Chacon ด้วยเช่นกัน
outis

@outis แปลก - ในเอกสาร HTML คอมไพล์สาขาการตรวจสอบออกมาก่อน rebasing <branch>จะเรียกว่าเป็น
Jesper Matthiesen

จุดดี. จะเป็นประโยชน์อย่างมากในการรวบรวม "git-terminology" ทั่วไปที่ไหนสักแห่ง โดยเฉพาะอย่างยิ่งสำหรับมือใหม่ (หรือ ppl ที่เอื้อต่อการคอมไพล์) จะช่วยให้ฉันมีความสุขกับการใช้ถ้อยคำของหน้า git
SebNag

@SebNag อะไรแบบนี้? linuxacademy.com/blog/linux/git-terms-explained
reggaeguitar

1
มาที่นี่จากgit-rebaseเอกสารเพราะฉันสับสนโดยสิ้นเชิงว่าเหตุใดผู้ตัดสินจะถูกเรียกว่า "อัปสตรีม" ที่นั่น (อันที่จริงฉันสงสัยตัวเองมากเพราะฉันไม่เคยเห็นคำศัพท์นี้มาก่อน) ขอบคุณ @outis & @matt สำหรับการล้างสิ่งต่าง ๆ !
Borek Bernard

0

โดยทั่วไป

  • ต้นน้ำขึ้นสู่แหล่งที่มา
  • ปลายน้ำไปทางอ่างล้างจานหรือปลายทาง

สิ่งนี้ใช้กับระบบที่มีลักษณะคล้ายต้นไม้ทั้งหมดรวมถึงระบบควบคุมแหล่งที่มา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.