ข้อผิดพลาดในการกด Git 'ต้นแบบถูกปฏิเสธจากระยะไกล -> ต้นแบบ (สาขาได้รับการชำระเงินในขณะนี้)'


961

เมื่อวานนี้ฉันโพสต์คำถามเกี่ยวกับวิธีการโคลนที่เก็บGitจากเครื่องหนึ่งไปยังอีกเครื่องฉันจะ 'git clone' จากเครื่องอื่นได้อย่างไร .

ตอนนี้ฉันสามารถโคลนที่เก็บ Git จากแหล่งที่มาของฉัน (192.168.1.2) ไปยังปลายทางของฉันได้สำเร็จแล้ว (192.168.1.1)

แต่เมื่อฉันแก้ไขไฟล์ a git commit -a -m "test"และ a git pushฉันได้รับข้อผิดพลาดนี้ที่ปลายทางของฉัน (192.168.1.1):

git push                                                
hap@192.168.1.2's password: 
Counting objects: 21, done.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (11/11), 1010 bytes, done.
Total 11 (delta 9), reused 0 (delta 0)
error: refusing to update checked out branch: refs/heads/master
error: By default, updating the current branch in a non-bare repository
error: is denied, because it will make the index and work tree inconsistent
error: with what you pushed, and will require 'git reset --hard' to match
error: the work tree to HEAD.
error: 
error: You can set 'receive.denyCurrentBranch' configuration variable to
error: 'ignore' or 'warn' in the remote repository to allow pushing into
error: its current branch; however, this is not recommended unless you
error: arranged to update its work tree to match what you pushed in some
error: other way.
error: 
error: To squelch this message and still keep the default behaviour, set
error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git+ssh://hap@192.168.1.2/media/LINUXDATA/working
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'git+ssh://hap@192.168.1.2/media/LINUXDATA/working'

ฉันใช้ Git สองรุ่นที่แตกต่างกัน (1.7 บนรีโมทและ 1.5 บนเครื่องท้องถิ่น) นั่นเป็นเหตุผลที่เป็นไปได้หรือไม่


5
ตัวจับเวลาเก่าใด ๆ สามารถเปลี่ยนคำตอบที่ยอมรับเป็นstackoverflow.com/a/9283833/397872และย้ายเธรดเพื่อเก็บถาวรหรืออะไรก็ได้? หรือเปลี่ยนความเป็นเจ้าของหรืออะไรก็ตาม
rishta

9
ตอนนี้คุณมีวิธีที่ปลอดภัยในการผลักดันไปยัง repo ที่ไม่ได้เปลือยด้วย Git 2.3.0 (กุมภาพันธ์ 2015) และgit config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

นั่นคือลิงค์ใหม่ของหนังสือที่ @stigi ได้กล่าวถึง: git-scm.com/book/en/v1/Git-on-the-Server
Abdelilah El Aissaoui


แต่ฉันไม่เข้าใจว่าทำไมและมันทำงานอย่างไร มันใช้งานได้ แต่นั่นคือทั้งหมด
Tilak Maddy

คำตอบ:


1149

คุณสามารถแปลงพื้นที่เก็บข้อมูลระยะไกลของคุณเป็นพื้นที่เก็บข้อมูลเปล่า (ไม่มีสำเนาการทำงานในพื้นที่เก็บข้อมูลเปลือย - โฟลเดอร์มีเพียงข้อมูลที่เก็บจริงเท่านั้น)

ดำเนินการคำสั่งต่อไปนี้ในโฟลเดอร์ที่เก็บระยะไกลของคุณ:

git config --bool core.bare true

จากนั้นลบไฟล์ทั้งหมดยกเว้น.gitในโฟลเดอร์นั้น จากนั้นคุณจะสามารถดำเนินการgit pushไปยังที่เก็บระยะไกลได้โดยไม่มีข้อผิดพลาดใด ๆ


4
ขอบคุณ ฉันต้องการสิ่งนี้ด้วย ฉันกำลังติดตาม submodules tutorial จากGit Community Bookและกดสิ่งกีดขวางบนถนนนี้
ชิกิ

6
ฉันไม่แน่ใจว่าคุณตั้งใจจะลบไฟล์บนเซิร์ฟเวอร์หรือลูกค้า ... ดังนั้นฉันจึงไม่ได้ลบอะไรเลยและปัญหาก็หายไปหลังจากทำgit config --bool core.bare trueไป มีเหตุผลใดบ้างที่จำเป็นต้องลบไฟล์บางไฟล์? ถ้าเป็นเช่นนั้นคุณจะแม่นยำมากขึ้นเกี่ยวกับสิ่งที่ต้องลบหรือไม่
Brian Vandenberg

24
มันเป็นคำตอบที่ดีที่สุดและไม่มีใครให้คำตอบในหลุม Interwebs ฉันคิดว่าพวกเราทุกคนมีข้อความแสดงข้อผิดพลาดเหมือนกันและพวกเราต่างก็ดีใจที่ได้อ่าน
Sebastián Grignoli

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

9
การเปลี่ยนแหล่งซื้อคืนกลับเป็นเปลือยเป็นเรื่องมากเกินไป ทั้งหมดที่คุณต้องทำคือการผลักดันให้เป็นสาขาใหม่ใน repo แหล่งที่มาเป็น @ Robert ชี้ให้เห็น: stackoverflow.com/a/2933656/402949
Dan Solovay

708

ฉันเพิ่งมีข้อผิดพลาดเดียวกันในขณะที่ผมเริ่มเรียนรู้Git คำตอบอื่น ๆ บางคำไม่ชัดเจนสำหรับผู้ที่เพิ่งเริ่มใช้ Git!

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

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

ฉันหวังว่านี่จะช่วยได้.


76
+1 มีประโยชน์มากยิ่งขึ้นขอบคุณ Robert ฉันไม่สมเหตุสมผลที่จะเปลี่ยนมาเป็น repo ที่เปลือยเปล่าในกรณีของฉัน เพียงแค่ต้อง 'ปิดการใช้งาน' สาขาที่คุณพยายามจะกด มีเหตุผล.
Eric Muyser

32
@ FMaz008: เพียงแค่สร้างสาขาหุ่น (git checkout -b dummy)
Dror Cohen

14
ผู้ชายคนนี้ดีกว่าคำตอบโหวตมากที่สุด :) ขอบคุณ ถึงแม้ว่าคำตอบอื่น ๆ ก็ช่วยได้เช่นกัน :)
Ivan Ivanić

103
เพื่อทำให้ชัดเจนขึ้นใน repo ซึ่งเป็นเป้าหมายของการผลักดัน: git checkout -b tmp. จากนั้นใน repo git pushแหล่งที่มา: จากนั้นกลับเข้าสู่เป้าหมาย (ไม่บังคับ):git checkout master; git branch -d tmp
Hari Karam Singh

18
ความคิดเห็นของ Hari เป็นสูตรที่ง่ายที่สุด ฉันต้องบอกว่าในขณะที่คอมไพล์อาจดีในหลาย ๆ ทางมาจาก svn หรืออาจ rv อื่น ๆ ทั้งหมดนี้เป็นสิ่งที่ไม่น่าใช้
ไม่มีเงื่อนไข ReinstateMonica

128

ข้อความแสดงข้อผิดพลาดอธิบายสิ่งที่เกิดขึ้น Git รุ่นที่ทันสมัยกว่าปฏิเสธที่จะอัปเดตสาขาผ่านการพุชหากมีการเช็กเอาต์สาขานั้น

วิธีที่ง่ายที่สุดในการทำงานระหว่างที่เก็บข้อมูลที่ไม่ได้เปลือยเปล่าสองแห่งนั้นคือ

  1. อัปเดตที่เก็บเสมอโดยดึง (หรือดึงข้อมูลและผสาน) หรือถ้าคุณต้อง

  2. โดยการผลักดันไปยังสาขาแยกต่างหาก (สาขานำเข้า) จากนั้นรวมสาขานั้นเข้ากับสาขาหลักบนเครื่องระยะไกล

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

สิ่งนี้จะทำให้ง่ายมากที่จะกระทำการเปลี่ยนแปลงโดยไม่ตั้งใจซึ่งยกเลิกการเปลี่ยนแปลงทั้งหมดที่ผลักดันและทำให้ยากที่จะแยกแยะความแตกต่างระหว่างการเปลี่ยนแปลงในท้องถิ่นใด ๆ ที่ยังไม่ได้รับการยอมรับและความแตกต่างระหว่างใหม่HEADดัชนีและแผนผังการทำงาน HEADเกิดจากการผลักดันการเคลื่อนย้าย


1
ขอบคุณ ดังนั้นฉันจะแก้ไขปัญหาของฉันได้อย่างไร ในกล่อง 192 ของฉันฉันได้ '$ cd (โครงการไดเรกทอรี) $ git init $ (เพิ่มบางไฟล์) $ git เพิ่ม' จากนั้นในกล่อง 191 ของฉันฉันทำ 'git clone' แล้วแก้ไขไฟล์บางไฟล์และลอง 'git push' แทน
hap497

16
ฉันอธิบายความเป็นไปได้ในคำตอบของฉัน คุณสามารถไปที่กล่อง 192 และดึงข้อมูลจากกล่อง 191 (คุณอาจต้องการเพิ่มกล่อง 191 เป็นชื่อระยะไกล - ดูที่git remote add box191 <191url>) หรือคุณสามารถกดจากกล่อง 191 ไปยังสาขาที่มีชื่ออื่น (เช่นgit push origin master:refs/heads/upload) จากนั้น ไปที่ 192 กล่องและผสาน (เช่นgit merge upload)
CB Bailey

3
ตอนนี้คุณมีวิธีที่ปลอดภัยในการผลักดันไปยัง repo ที่ไม่ได้เปลือยด้วย Git 2.3.0 (กุมภาพันธ์ 2015) และgit config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309 : คุณไม่ต้องการตัวเลือก 2 อีกต่อไป
VonC

122

สรุป

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

เนื่องจากที่เก็บเปลือยไม่เคยมีสาขาที่เช็คเอาท์คุณสามารถกดไปที่สาขาใดก็ได้ของที่เก็บเปลือย

มีวิธีแก้ไขหลายวิธีขึ้นอยู่กับความต้องการของคุณ

โซลูชันที่ 1: ใช้ Repostiory เปลือย

ตามที่แนะนำถ้าในเครื่องเดียวคุณไม่ต้องการไดเรกทอรีทำงานคุณสามารถย้ายไปยังที่เก็บเปล่า เพื่อหลีกเลี่ยงการยุ่งกับที่เก็บคุณสามารถโคลนมันได้:

machine1$ cd ..
machine1$ mv repo repo.old
machine1$ git clone --bare repo.old repo

ตอนนี้คุณสามารถกดทั้งหมดที่คุณต้องการไปยังที่อยู่เดิมเหมือนเดิม

โซลูชันที่ 2: กดไปยังสาขาที่ไม่ได้ชำระเงิน

แต่ถ้าคุณต้องการตรวจสอบรหัสบนรีโมตของ<remote>คุณคุณสามารถใช้สาขาพิเศษเพื่อพุช สมมติว่าในพื้นที่เก็บข้อมูลในพื้นที่ของคุณคุณได้เรียกใช้รีโมตของoriginคุณแล้ว จากนั้นคุณสามารถทำได้

machine2$ git push origin master:master+machine2

จากนั้นคุณจะต้องรวมมันเมื่อคุณอยู่ในoriginrepo ระยะไกล:

machine1$ git merge master+machine2

การชันสูตรพลิกศพของปัญหา

เมื่อสาขาถูกเช็กเอาต์การคอมมิตจะเพิ่มการคอมมิตใหม่กับส่วนหัวสาขาปัจจุบันเป็นพาเรนต์และย้ายส่วนหัวของสาขาไปเป็นการคอมมิชชันใหม่

ดังนั้น

A ← B
    ↑
[HEAD,branch1]

กลายเป็น

A ← B ← C
        ↑
    [HEAD,branch1]

แต่ถ้ามีใครสามารถกดไปที่สาขานั้นในระหว่างผู้ใช้จะได้รับสิ่งที่เรียก git เรียกโหมดหัวเดี่ยว :

A ← B ← X
    ↑   ↑
[HEAD] [branch1]

ตอนนี้ผู้ใช้ไม่ได้อยู่ใน branch1 อีกต่อไปโดยไม่ต้องขอให้ตรวจสอบสาขาอื่นอย่างชัดเจน เลวร้ายยิ่งกว่าผู้ใช้อยู่นอกสาขาใด ๆ และการกระทำใหม่ใด ๆ ก็จะห้อยต่องแต่ง :

      [HEAD]
        ↓
        C
      ↙
A ← B ← X
        ↑
       [branch1]

สมมุติฐานถ้าที่จุดนี้จะตรวจสอบผู้ใช้ออกจากสาขาอื่นแล้วห้อยนี้กระทำจะกลายเป็นเกมที่ยุติธรรมสำหรับ Git ของการเก็บขยะ


3
การแก้ไขทางเทคนิคอย่างหนึ่งสำหรับ "การชันสูตรศพ": git จะไม่แยกออกHEADจากที่เก็บข้อมูลแบบพุชไปยัง HEADจะยังคงชี้ไปที่สาขาและสาขาจะหันไปมุ่งมั่นใหม่ (s) ผลัก; แต่ไดเรกทอรีการทำงานและดัชนี / การจัดเตรียมพื้นที่จะไม่ได้รับการแก้ไข ใครก็ตามที่ทำงานบนพื้นที่เก็บข้อมูลแบบพุชไปยังตอนนี้ต้องทำงานอย่างหนักเพื่อกู้คืนจากผลกระทบของการพุช: พิจารณาว่ามีการเปลี่ยนแปลงใด ๆ ที่จะบันทึกหรือไม่
torek

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

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

ฉันสร้างโฟลเดอร์ GIT ในเซิร์ฟเวอร์ของฉันซึ่งจะโฮสต์ที่เก็บทั้งหมดที่สร้างโดยผู้ใช้หลายคนโดยใช้ SourceTree ฉันสร้างที่masterเก็บในพีซีของฉัน ฉันเพิ่มremotesไปยังโฟลเดอร์เซิร์ฟเวอร์และพยายามดันที่เก็บของฉันลงในเซิร์ฟเวอร์เพื่อให้ผู้ใช้รายอื่นสามารถดึง / ดึงข้อมูลเพื่อให้ทำงานได้ ฉันได้รับข้อผิดพลาดต่อไปนี้: ! [remote rejected] master -> master (branch is currently checked out)ฉันจะเช็คอินได้อย่างไร?
SearchForKnowledge

1
@SearchForKnowledge คุณรู้หรือไม่ว่าคุณกำลังถามคำถามที่ฉันตอบอยู่ใช่มั้ย!
ไม่มีที่ไหนเลยผู้ชาย

65

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

[receive]
denyCurrentBranch = warn

หรือ

[receive]
denyCurrentBranch = false

ครั้งแรกที่จะช่วยให้การผลักดันในขณะที่เตือนความเป็นไปได้ที่จะเลอะสาขาในขณะที่สองจะเงียบ ๆ ยอมให้มัน

สามารถใช้เพื่อ "ปรับใช้" รหัสไปยังเซิร์ฟเวอร์ซึ่งไม่ได้มีไว้สำหรับการแก้ไข นี่ไม่ใช่วิธีที่ดีที่สุด แต่เป็นวิธีที่รวดเร็วในการปรับใช้รหัส


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

10
ฉันใช้วิธีการด้านบนพร้อมcd .. && git reset --hardตะขอเกี่ยวเพื่อนำไปใช้งาน Hackish แต่ใช้งานได้
jholster

9
รุ่นบรรทัดคำสั่งของหลังจะเป็นgit config receive.denyCurrentBranch warn
อังเดรโฮลเนอร์

4
นี่ควรเป็นคำตอบที่ยอมรับได้ พวกเราบางคนรู้ว่าเรากำลังทำอะไรอยู่และไม่ใช่ผู้เริ่มต้น Git นี่คือคำตอบสำหรับคนเหล่านั้น
Qix - MONICA ถูกยกเลิกเมื่อ

2
ฮา แต่คำถามไม่ได้ถูกถามโดยคนเหล่านั้น
ไม่มีที่ไหนเลยชาย

46

git config --local receive.denyCurrentBranch updateInstead

https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

ใช้สิ่งนั้นบนที่เก็บเซิร์ฟเวอร์และอัพเดตทรีการทำงานหากไม่มีการเขียนทับที่ไม่ได้ติดตามจะเกิดขึ้น

มันถูกเพิ่มเข้ามาในGit 2.3เป็นที่กล่าวถึงโดย VonCในการแสดงความคิดเห็น

ฉันรวบรวม Git 2.3 แล้วลองดู ตัวอย่างการใช้งาน:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

เอาท์พุท:

a
b

ย่ะbโดนผลัก!


@VonC ขอบคุณ! มันเป็นความหลงไหลของฉันกับตัวอย่างเล็ก ๆ น้อย ๆ ในที่ทำงาน :-)
Ciro Santilli 冠状病毒审查六四事件法轮功

สิ่งนี้มีปัญหากับการยอมรับการเปลี่ยนแปลงที่ไม่ทันสมัยกับเซิร์ฟเวอร์หรือไม่?
akozi

@akozi ฉันไม่แน่ใจว่าคุณหมายถึงอะไรถ้าคุณกระทำในพื้นที่ก่อนที่จะดึงมันจะทำตัวเหมือน--bareโคลนแบบดั้งเดิมที่ฉันคิดว่า: --forceจำเป็นต้องผลักดันและมันจะทำให้คุณ "เสีย" มุ่งมั่นในระยะไกล
Ciro Santilli 冠状病毒审查六四事件法轮功

1
@CiroSantilli 新疆改造中心六四事件法轮功ไม่ต้องกังวลตอนนี้ ฉันค้นหาความหมายของตัวเลือกต่างๆ ฉันคิดว่า updateInstead มีความหมายเหมือนกันกับการบังคับ
akozi

updateInstead ไม่มีค่าที่ถูกต้องอีกต่อไปสำหรับ
receive.denyCurrentBranch

41

ฉันชอบความคิดที่ยังคงมีพื้นที่เก็บข้อมูลที่ใช้งานได้ในกล่องระยะไกล แต่แทนที่จะเป็นสาขาจำลองฉันต้องการใช้:

git checkout --detach

นี่เป็นคุณสมบัติใหม่ของGit - ฉันใช้ git เวอร์ชั่น 1.7.7.4


8
และหลังจากผลักดันการเปลี่ยนแปลงของคุณคุณสามารถใช้: git checkout masterเพื่อกลับไปที่สาขาหลัก หลังจากนั้นการเปลี่ยนแปลงของคุณจะถูกนำไปใช้
MAZDAK

30

ฉันมีปัญหาเดียวกัน สำหรับฉันฉันใช้ Git push เพื่อย้ายรหัสไปยังเซิร์ฟเวอร์ของฉัน ฉันไม่เคยเปลี่ยนรหัสทางฝั่งเซิร์ฟเวอร์ดังนั้นจึงปลอดภัย

ในที่เก็บคุณกำลังกดเพื่อพิมพ์:

git config receive.denyCurrentBranch ignore

สิ่งนี้จะช่วยให้คุณสามารถเปลี่ยนที่เก็บในขณะที่มันเป็นสำเนาการทำงาน

หลังจากที่คุณใช้งาน Git แล้วให้ไปที่เครื่องระยะไกลและพิมพ์สิ่งนี้:

git checkout -f

สิ่งนี้จะทำให้การเปลี่ยนแปลงที่คุณผลักปรากฏในสำเนาทำงานของเครื่องระยะไกล

โปรดทราบว่านี่อาจไม่ปลอดภัยเสมอไปหากคุณทำการเปลี่ยนแปลงในสำเนาการทำงานที่คุณใช้งาน


ขอบคุณบันทึกฉันรวมข้อเสนอแนะของคุณdenyCurrentBranchและใส่git checkout -fในhooksโฟลเดอร์เช่น @ jack-senechal โพสต์ที่นี่
Éderson T. Szlachta

มีวิธีทำให้ไฟล์ปรากฏบนพื้นที่เก็บข้อมูลระยะไกลโดยไม่ต้องไปและทำคำสั่งนี้หรือไม่? คือคำสั่งจากท้องถิ่นหรือไม่
Royi

24

คุณสามารถสร้างที่เก็บเซิร์ฟเวอร์ของคุณขึ้นมาใหม่และผลักดันจากต้นแบบสาขาโลคัลไปยังต้นแบบเซิร์ฟเวอร์

บนเซิร์ฟเวอร์ระยะไกลของคุณ:

mkdir myrepo.git
cd myrepo.git
git init --bare

ตกลงจากสาขาท้องถิ่นของคุณ:

git push origin master:master

3
ขอบคุณนี่เป็นคำตอบสำหรับฉันเพราะฉันไม่ได้ใช้ '--bare' บนเซิร์ฟเวอร์ระยะไกล ดูเหมือนว่าคำตอบสำหรับคำถามนี้ขึ้นอยู่กับว่าคุณใช้ repo เซิร์ฟเวอร์ระยะไกลเป็นไดเรกทอรีการทำงานหรือไม่และในกรณีนี้เป็นคำตอบที่ถูกต้อง
Cas

2
ฉันไม่เข้าใจ: SI พยายามที่จะสร้างและโคลน repo เปล่า แต่โคลนดาวน์โหลดอะไรและผลักดันสิ่งที่อัปโหลดดังนั้นนี้ไม่ทำงาน ... :-) ฉันอ่านบทเรียนเกี่ยวกับ repos เปลือย แต่พวกเขาบอกว่า repo เปลือย ไม่มีไฟล์ ... นั่นไม่ใช่สิ่งที่ฉันกำลังมองหา ...
inf3rno

22

สิ่งที่คุณอาจทำให้เกิดสิ่งนี้:

สิ่งนี้เกิดขึ้นเมื่อคุณออกรายการเล็ก ๆ คุณกำลังจะเปลี่ยนสิ่งที่ใช้งานได้อยู่แล้วดังนั้นคุณจึงสะกดคาถาระดับ 3 ของการเลิกทำแบบไม่ถาวร:

machine1:~/proj1> git init

และคุณเริ่มเพิ่ม / กระทำ แต่แล้วโครงการก็เริ่มมีส่วนร่วมมากขึ้นและคุณต้องการทำงานจากคอมพิวเตอร์เครื่องอื่น (เช่นพีซีหรือแล็ปท็อปที่บ้าน) ดังนั้นคุณจึงทำสิ่งที่ชอบ

machine2:~> git clone ssh://machine1/~/proj1

และมันโคลนและทุกอย่างดูดีและคุณทำงานกับรหัสของคุณจาก machine2

จากนั้น ... คุณพยายามผลักดันคอมมิชชันของคุณจาก machine2 และคุณได้รับข้อความเตือนในชื่อเรื่อง

สาเหตุของข้อความนี้เป็นเพราะ repo git ที่คุณดึงมานั้นตั้งใจที่จะใช้สำหรับโฟลเดอร์นั้นใน machine1 คุณสามารถโคลนนิ่งจากมันได้ดี แต่การกดอาจทำให้เกิดปัญหาได้ วิธี "เหมาะสม" ในการจัดการรหัสในสองสถานที่ต่างกันคือ "ซื้อคืน" ที่ว่างเปล่าอย่างที่ได้รับการแนะนำ Repo เปลือยไม่ได้ออกแบบมาเพื่อให้มีการทำงานใด ๆในนั้นมันหมายถึงการประสานงานความมุ่งมั่นจากหลายแหล่ง นี่คือเหตุผลที่คำตอบยอดนิยมแสดงให้เห็นการลบไฟล์ทั้งหมด / โฟลเดอร์อื่นนอกเหนือจากโฟลเดอร์ .git git config --bool core.bare trueหลังจากที่คุณ

การอธิบายคำตอบที่ได้รับความนิยมสูงสุด:ความคิดเห็นหลายคำตอบพูดเช่น "ฉันไม่ได้ลบไฟล์ที่ไม่ใช่. git จาก machine1 และฉันก็ยังสามารถคอมมิชชันจาก machine2" ถูกตัอง. อย่างไรก็ตามไฟล์อื่น ๆ เหล่านั้น "หย่าร้าง" อย่างสมบูรณ์จาก git repo ในตอนนี้ ลองgit statusเข้าไปที่นั่นแล้วคุณจะเห็นบางอย่างเช่น "ร้ายแรง: การดำเนินการนี้จะต้องทำงานในต้นไม้ทำงาน" ดังนั้นข้อเสนอแนะในการลบไฟล์ที่ไม่เป็นเช่นนั้นที่กระทำจากน้ำพระทัยเครื่องจักร 2 การทำงาน ; เพื่อที่คุณจะได้ไม่สับสนและคิดว่าคอมไพล์ยังติดตามไฟล์เหล่านั้นอยู่ แต่การลบไฟล์นั้นเป็นปัญหาหากคุณยังต้องการทำงานกับไฟล์ใน machine1 ใช่ไหม

ดังนั้นคุณควรทำอย่างไรดี

ขึ้นอยู่กับว่าคุณวางแผนจะทำงานกับ machine1 และ machine2 เท่าใด ...

หากคุณกำลังพัฒนาจาก machine1 และย้ายการพัฒนาทั้งหมดของคุณไปยัง machine2 ...เพียงแค่ทำตามคำตอบที่ได้รับการแนะนำ: git config --bool core.bare trueจากนั้นเลือกลบไฟล์ / โฟลเดอร์ทั้งหมดที่ไม่ใช่. git จากโฟลเดอร์นั้นเนื่องจากพวกเขา ไม่ได้ติดตามและมีแนวโน้มที่จะทำให้เกิดความสับสน

หากงานของคุณใน machine2 เป็นเพียงครั้งเดียวและคุณไม่จำเป็นต้องพัฒนาต่อไปที่นั่น ...จากนั้นอย่ากังวลกับการทำ repo เปล่า เพียง ftp / rsync / scp / etc ไฟล์ของคุณจากเครื่อง * 2 * ที่ด้านบนของไฟล์ในเครื่อง * 1 * กระทำ / ส่งจากเครื่อง * 1 * แล้วลบไฟล์ออกจากเครื่อง * 2 * คนอื่น ๆ แนะนำให้สร้างสาขา แต่ฉันคิดว่ามันยุ่งเหยิงนิดหน่อยถ้าคุณต้องการรวมการพัฒนาบางอย่างที่คุณทำในแบบครั้งเดียวจากเครื่องอื่น

หากคุณต้องการพัฒนาทั้ง machine1 และ machine2ต่อไปคุณต้องตั้งค่าต่าง ๆ ให้เหมาะสม คุณจำเป็นต้องแปลง repo ของคุณเป็นชุดเปล่าจากนั้นคุณต้องทำการโคลนบนเครื่อง 1 เพื่อให้คุณสามารถทำงานได้วิธีที่เร็วที่สุดในการทำเช่นนี้คือการทำ

machine1:~/proj1> git config --bool core.bare true
machine1:~/proj1> mv .git/ ../proj1.git
machine1:~/proj1> cd ..
machine1:~> rm -rf proj1
machine1:~> git clone proj1.git
machine1:~> cd proj1

ที่สำคัญมาก:เพราะคุณได้ย้ายสถานที่ตั้งของธุรกรรมซื้อคืนจาก proj1 เพื่อ proj1.git ที่คุณจำเป็นต้องปรับปรุงนี้ใน .git / config ไฟล์บนเครื่องจักร 2 หลังจากนั้นคุณสามารถคอมมิทการเปลี่ยนแปลงของคุณจาก machine2 สุดท้ายฉันพยายามเก็บ repos เปลือยของฉันไว้ในที่ตั้งห่างจากต้นไม้ที่ทำงาน (เช่นอย่าใส่ 'proj1.git' ในโฟลเดอร์พาเรนต์เดียวกันกับ 'proj1') ฉันแนะนำให้คุณทำเช่นเดียวกัน แต่ฉันต้องการให้ขั้นตอนข้างต้นง่ายที่สุดเท่าที่จะทำได้


มีรายละเอียดมากและเป็นประโยชน์ กรณีของฉันเป็นคดีสุดท้ายและคำแนะนำของคุณทำงานได้อย่างมีเสน่ห์
pojda

ฉันในกรณีที่ 3 และฉันทำสิ่งที่แตกต่างออกไปเล็กน้อย: mk git-server; mv .git git-server / proj.git จากนั้น git clone git-server / proj.git ไปที่ 1 และ 2 (หรือ git remote remote ... ) โดยใช้ ssh: // คำนำหน้าสำหรับเครื่อง 2 ด้วยวิธีนี้ ฉันจะเก็บสำเนาต้นฉบับเปลือยซึ่งจะเป็นเหมือนปกติใน GH หรือเซิร์ฟเวอร์ HTTP อื่น ๆ และฉันจะใช้ push / pull บนเครื่องทั้งสอง
zakmck

18

ด้วยขั้นตอนการตั้งค่าเล็กน้อยคุณสามารถปรับใช้การเปลี่ยนแปลงในเว็บไซต์ของคุณได้อย่างง่ายดายโดยใช้สายการบินเดียว

git push production

สิ่งที่ดีและเรียบง่ายและคุณไม่จำเป็นต้องล็อกอินเข้าสู่เซิร์ฟเวอร์ระยะไกลและทำการดึงหรืออะไรก็ตาม โปรดทราบว่าวิธีนี้จะได้ผลดีที่สุดหากคุณไม่ได้ใช้การชำระเงินการผลิตเป็นสาขาที่ใช้งานได้! (OP ทำงานในบริบทที่แตกต่างกันเล็กน้อยและฉันคิดว่าโซลูชันของ @Robert Gould กล่าวถึงได้ดีวิธีนี้เหมาะสำหรับการปรับใช้กับเซิร์ฟเวอร์ระยะไกล)

ก่อนอื่นคุณต้องตั้งค่าที่เก็บเปลือยบนเซิร์ฟเวอร์ของคุณนอก webroot ของคุณ

mkdir mywebsite.git
cd mywebsite.git
git init --bare

จากนั้นสร้างไฟล์hooks/post-receive:

#!/bin/sh
GIT_WORK_TREE=/path/to/webroot/of/mywebsite git checkout -f

และทำให้ไฟล์ปฏิบัติการได้:

chmod +x hooks/post-receive

บนเครื่องของคุณ

git remote add production git@myserver.com:mywebsite.git
git push production +master:refs/heads/master

ทุกชุด! ในอนาคตคุณสามารถใช้git push productionเพื่อปรับใช้การเปลี่ยนแปลงของคุณ!

สินเชื่อเพื่อการแก้ปัญหานี้ไปเพื่อhttp://sebduggan.com/blog/deploy-your-website-changes-using-git/ ดูคำอธิบายโดยละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่เกิดขึ้น


ข้อเสนอแนะของคุณช่วยฉันได้มาก แต่ฉันไม่ได้ใช้bareฉันทำตามสิ่งนี้และผสานเข้ากับhooks(ที่คุณแนะนำ) และทำงานอย่างสมบูรณ์
Éderson T. Szlachta

11

คุณควรผลักดันไปยังพื้นที่เก็บข้อมูลเปล่า ที่เก็บเปลือยคือที่เก็บที่ไม่มีสาขาที่เช็กเอาต์ ถ้าคุณต้องไปยังไดเร็กตอรี่ repository ของเปลือยคุณจะเห็นเฉพาะเนื้อหาของไดเรกทอรี. git เท่านั้น


9
ไม่มีอะไรผิดปกติกับการผลักดันไปยังสาขาที่ไม่ได้ชำระเงินในพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยเปล่า นี่เป็นวิธีการทำงานที่ถูกต้องสมบูรณ์แบบ
CB Bailey

ยุติธรรมเพียงพอที่จะทำงาน แต่นั่นไม่ใช่สิ่งที่ผู้ใช้กำลังทำ
RibaldEddie

13
ไม่ใช่ความจริงที่ว่าเขาไม่ได้ใช้ที่เก็บเปลือยที่ 'ผิด'; มันเป็นความจริงที่ว่าเขาผลักดันให้สาขาที่เช็คเอาท์ ไม่มีหลักฐานว่าเขามีหรือต้องการที่เก็บเปลือยแยกต่างหากดังนั้นคำสั่งครอบคลุมของคุณว่าเขาควรจะผลักดันไปยังพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยเท่านั้นไม่ได้ให้ตัวเลือกทั้งหมดแก่ผู้ถาม หนึ่งในนั้นอาจแก้ปัญหาได้ง่ายขึ้น
CB Bailey

10

คุณมี 3 ตัวเลือก

  1. ดึงแล้วดันอีกครั้ง:

    git pull; git push
    
  2. ผลักดันเข้าไปในสาขาที่แตกต่างกัน:

    git push origin master:foo
    

    และรวมมันในระยะไกล (โดยgitหรือดึงคำขอ )

    git merge foo
    
  3. บังคับใช้ (ไม่แนะนำเว้นแต่คุณจะทำการเปลี่ยนแปลงโดยเจตนาrebase):

    git push origin master -f
    

    หากยังคงปฏิเสธให้ปิดการใช้งานdenyCurrentBranch ในที่เก็บระยะไกล:

    git config receive.denyCurrentBranch ignore
    

ตัวเลือก 2 ใช้ได้สำหรับฉัน remote git init local git push master กำเนิด: branch remote git merge DONE
Jacky Chong

7

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


7

ตรวจสอบ.git/configโครงการปลายทางของคุณ:

$ cat .git/config 
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[receive]
    denyCurrentBranch = updateInstead

หากcore. bareเป็นเท็จคุณสามารถตั้งค่าเป็นจริง:

$ git config core.bare true

และจากนั้นในท้องถิ่นของคุณไปยังรีโมท:

git push remote_repo   // suppose the destination repo is remote_repo

มันจะประสบความสำเร็จใน remote_repo คุณสามารถตรวจสอบรุ่น git

$ git log -1
commit 0623b1b900ef7331b9184722a5381bbdd2d935ba
Author: aircraft < aircraft_xxx@126.com>
Date:   Thu May 17 21:54:37 2018 +0800

และตอนนี้คุณไม่สามารถใช้คอมไพล์ใน "พื้นที่ทำงาน" ของคุณ:

$ git status
fatal: This operation must be run in a work tree

คุณควรตั้งbare.bareกลับเป็นเท็จ

$ git config core.bare false

5

ฉันมีปัญหาเดียวกันกับการใช้ Git เพื่อซิงโครไนซ์ที่เก็บข้อมูลบนโทรศัพท์ Android และแล็ปท็อปของฉัน ทางออกสำหรับฉันคือทำแบบดึงแทนที่จะเป็นแบบกดตามที่ @CharlesBailey แนะนำ

git push origin master บนที่เก็บ Android ล้มเหลวสำหรับฉันพร้อมกับข้อความแสดงข้อผิดพลาดเดียวกับที่ @ hap497 ได้รับเนื่องจากการพุชไปยังการชำระเงินที่ไม่ใช่การส่งของ repository + working-copy

git pull droid masterบนที่เก็บแล็ปท็อปและสำเนาการทำงานใช้ได้สำหรับฉัน git remote add droid /media/KINGSTON4GB/notes_repo/แน่นอนคุณจะต้องมีการทำงานก่อนหน้านี้สิ่งที่ต้องการ


4

Git เวอร์ชันที่เก่ากว่าใช้เพื่ออนุญาตการพุชไปยังสาขาที่เช็กเอาต์ในปัจจุบันของที่เก็บที่ไม่ได้เปลือย

ปรากฎว่านี่เป็นสิ่งที่ทำให้เกิดความสับสนอย่างมากที่จะอนุญาต ดังนั้นพวกเขาจึงเพิ่มข้อความเตือนที่คุณเห็นซึ่งสร้างความสับสนอย่างมาก

หากที่เก็บข้อมูลแรกทำหน้าที่เป็นเซิร์ฟเวอร์ให้แปลงเป็นพื้นที่เก็บข้อมูลเปล่าเป็นคำตอบอื่น ๆ ที่แนะนำและทำได้ด้วย

อย่างไรก็ตามหากคุณจำเป็นต้องมีสาขาที่ใช้ร่วมกันระหว่างสอง repos ที่ใช้งานอยู่ทั้งคู่คุณสามารถทำได้โดยใช้การตั้งค่าต่อไปนี้

Repo1 - จะทำหน้าที่เป็นเซิร์ฟเวอร์และใช้สำหรับการพัฒนา

Repo2 - สำหรับการพัฒนาเท่านั้น

ตั้งค่า Repo1 ดังนี้

สร้างสาขาเพื่อแบ่งปันงาน

git branch shared_branch

เพื่อความปลอดภัยคุณควรสร้าง $ (REPO) .git / hooks / update ที่ปฏิเสธการเปลี่ยนแปลงใด ๆ ที่นอกเหนือจาก shared_branch เนื่องจากคุณไม่ต้องการให้คนอื่นล้อเลียนสาขาส่วนตัวของคุณ

repo1/.git/hooks  (GIT_DIR!)$ cat update
#!/bin/sh
refname="$1"
oldrev="$2"
newrev="$3"

if [ "${refname}" != "refs/heads/shared_branch" ]
then
   echo "You can only push changes to shared_branch, you cannot push to ${refname}"
   exit 1
fi

ตอนนี้สร้างสาขาท้องถิ่นใน repo1 ที่คุณจะทำงานจริงของคุณ

git checkout -b my_work --track shared_branch
Branch my_work set up to track local branch shared_branch.
Switched to a new branch 'my_work'

(อาจต้องgit config --global push.default upstreamเพื่อให้git pushสามารถทำงานได้)

ตอนนี้คุณสามารถสร้าง repo2 ด้วย

git clone path/to/repo1 repo2 
git checkout shared_branch 

ณ จุดนี้คุณมีทั้งการตั้งค่า repo1 และ repo2 เพื่อทำงานกับสาขาในพื้นที่ที่ผลักและดึงจากshared_branchใน repo1 โดยไม่ต้องกังวลเกี่ยวกับข้อความแสดงข้อผิดพลาดนั้นหรือทำให้ไดเรกทอรีการทำงานหลุดจากการซิงค์ใน repo1 ไม่ว่าเวิร์กโฟลว์ปกติที่คุณใช้จะทำงานอย่างไร


3

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

ตัวอย่างเช่นบนเซิร์ฟเวอร์ระยะไกล:

git branch dev
git checkout dev

ในการตั้งค่าท้องถิ่น:

git push 

บนเซิร์ฟเวอร์ระยะไกล:

git merge dev

2

นี่คือการทดสอบหนึ่งอย่างที่คุณสามารถทำได้เพื่อดูว่าbareเซิร์ฟเวอร์ทำงานอย่างไร:

ลองนึกภาพคุณมีเวิร์กสเตชันและเซิร์ฟเวอร์ที่มีไซต์สดที่โฮสต์อยู่และคุณต้องการอัปเดตไซต์นี้เป็นครั้งคราว (นี่ยังใช้กับสถานการณ์ที่ผู้พัฒนาสองรายกำลังส่งงานกลับไปกลับมาผ่านพ่อค้าคนกลาง)

การเริ่มต้น

สร้างไดเรกทอรีบางส่วนบนเครื่องคอมพิวเตอร์ของคุณและcdลงในนั้นดำเนินการคำสั่งเหล่านี้:

# initialization
git init --bare server/.git
git clone server content
git clone server local
  1. ขั้นแรกคุณต้องสร้างserverไดเรกทอรีเปล่า(สังเกตว่า. git ที่ท้าย) ไดเรกทอรีนี้จะทำหน้าที่เป็นที่เก็บไฟล์สำหรับที่เก็บของคุณเท่านั้น
  2. จากนั้นโคลนที่เก็บเซิร์ฟเวอร์ของคุณไปยังcontentไดเรกทอรีที่สร้างขึ้นใหม่ นี่คือไดเรกทอรีสด / ผลิตของคุณซึ่งจะให้บริการโดยซอฟต์แวร์เซิร์ฟเวอร์ของคุณ
  3. สองไดเรกทอรีแรกอยู่บนเซิร์ฟเวอร์ของคุณไดเรกทอรีที่สามเป็นไดเรกทอรีท้องถิ่นบนเวิร์กสเตชันของคุณ

ขั้นตอนการทำงาน

ตอนนี้ที่นี่เป็นเวิร์กโฟลว์พื้นฐาน:

  1. ป้อนlocalไดเรกทอรีสร้างไฟล์บางไฟล์แล้วคอมมิท ในที่สุดก็ผลักพวกเขาไปยังเซิร์ฟเวอร์:

    # create crazy stuff
    git commit -av
    git push origin master
    
  2. ตอนนี้เข้าสู่contentไดเรกทอรีและปรับปรุงเนื้อหาของเซิร์ฟเวอร์:

    git pull
    
  3. ทำซ้ำ 1-2 ที่นี่contentอาจเป็นผู้พัฒนารายอื่นที่สามารถผลักดันไปยังเซิร์ฟเวอร์ได้เช่นกันและlocalตามที่คุณอาจดึงมาจากเขา


2

การใช้สิ่งนี้เพื่อผลักดันมันไปยังสาขาต้นน้ำระยะไกลแก้ไขปัญหานี้ให้ฉัน:

git push <remote> master:origin/master

รีโมตไม่สามารถเข้าถึง repo ต้นน้ำดังนั้นนี่เป็นวิธีที่ดีในการรับการเปลี่ยนแปลงล่าสุดในรีโมตนั้น


1
มากกว่าปกติ (เช่นนี้เป็นผลสุทธิจากคำสั่ง) git push <remote> master:newbranchโดยใช้ แนวคิดคือคุณผลักสาขาใหม่ไปยังรีโมตซึ่งสามารถผสานเข้าด้วยกันวิธีนี้คุณจะหลีกเลี่ยงปัญหาความไม่สอดคล้องใด ๆ ที่กล่าวถึงในข้อความแสดงข้อผิดพลาด
ดิน

1

ฉันต้องเรียกใช้อีกครั้งgit --initในพื้นที่เก็บข้อมูลเปลือยที่มีอยู่และสิ่งนี้ได้สร้าง.gitไดเรกทอรีภายในแผนผังพื้นที่เก็บข้อมูลเปลือยฉันรู้ว่าหลังจากพิมพ์ที่git statusนั่น ฉันลบมันแล้วทุกอย่างก็ดีอีก :)

(คำตอบทั้งหมดนี้ยอดเยี่ยม แต่ในกรณีของฉันมันเป็นสิ่งที่แตกต่างอย่างสิ้นเชิง (เท่าที่ฉันเห็น) ตามที่อธิบายไว้)


1

ฉันแน่ใจว่าคนส่วนใหญ่ที่ดูคำถามนี้จะหยุดในสองคำตอบแรก ๆ แต่ฉันก็ยังอยากเสนอทางออกให้ฉัน

ฉันมีการตั้งค่าโครงการเว็บ Eclipse + EGit เมื่อพบข้อผิดพลาดที่อธิบายไว้ สิ่งที่ช่วยฉันได้คือเพียงแค่ใช้แอพ GitHub ซึ่งดูเหมือนจะแก้ไขปัญหาได้อย่างน่าอัศจรรย์ ในขณะที่ EGit มักจะปฏิเสธการผลักดันแอปเดสก์ท็อป GitHub จะยักไหล่และผลักดันการเปลี่ยนแปลงของฉัน บางทีมันอาจจัดการสถานการณ์การล็อกอินหลายอย่างได้อย่างสง่างาม


1

ฉันบทความพบว่าอาจเป็นประโยชน์กับผู้อื่นเป็นGit ใน 5 นาที

ฉันมีโครงการXcodeภายใต้การควบคุมเวอร์ชัน Git ที่ฉันต้องการผลักดันไปยังVirtual Distributed Ethernet (VDE) ที่ฉันมีใน DC VDE รันCentos 5

ไม่มีบทความที่ฉันอ่านเกี่ยวกับ Git ที่พูดถึงที่เก็บข้อมูลเปลือย มันฟังดูง่ายมากจนกระทั่งฉันลองทำในสิ่งที่ฉันคิดว่าน่าจะง่ายจากพื้นหลังของSVN

คำแนะนำที่นี่เพื่อให้พื้นที่เก็บข้อมูลระยะไกลเปลือยทำงาน ดียิ่งกว่าสำหรับความต้องการของฉันคือการโคลนโครงการ Xcode ไปprojectname.gitคัดลอกไปยังเซิร์ฟเวอร์ระยะไกล; จากนั้นผลักดันการทำงานอย่างน่าอัศจรรย์ ขั้นตอนต่อไปจะทำให้ Xcode ดันโดยไม่มีข้อผิดพลาดเกี่ยวกับการคอมมิท แต่ตอนนี้ฉันโอเคแล้วจาก Terminal

ดังนั้น:

cd /tmp (or another other directory on your system)<br/>
git clone --bare /xcode-project-directory projectname.git<br/>
scp -r projectname.git sshusername@remotehost.com:repos/<br/>

วิธีผลักดันการเปลี่ยนแปลงจากโปรเจ็กต์ Xcode ของคุณหลังจากที่คุณคอมมิชชันใน Xcode:

cd /xcode-project-directory<br/>
git push sshusername@remotehost.com:repos/projectname.git<br/>

ฉันแน่ใจว่ามีวิธีที่ซับซ้อนมากขึ้นในการทำข้างต้น แต่อย่างน้อยงานนี้ เพื่อให้ทุกอย่างชัดเจนนี่คือคำอธิบายบางอย่าง: /xcode-project-directoryเป็นไดเรกทอรีโครงการ Xcode /Users/Your_Name/Documents/Project_Nameของคุณจะถูกเก็บไว้ในมันอาจจะ. projectname เป็นชื่อของโครงการอย่างแท้จริง แต่สามารถเป็นอะไรก็ได้ที่คุณอยากเรียก Git ไม่สนใจคุณจะ

ในการใช้ scp คุณต้องมีบัญชีผู้ใช้บนเซิร์ฟเวอร์ระยะไกลที่ได้รับอนุญาต เข้าถึงSSH ทุกคนที่ใช้เซิร์ฟเวอร์ของตัวเองจะมีสิ่งนี้ หากคุณใช้โฮสติ้งที่ใช้ร่วมกันหรือสิ่งที่คล้ายกันคุณอาจโชคไม่ดี

remotehost.comเป็นชื่อของโฮสต์ระยะไกลของคุณ คุณสามารถใช้ที่อยู่ IP ได้อย่างง่ายดาย เพียงเพื่อความชัดเจนเพิ่มเติมฉันใช้Gitosisบนรีโมทโฮสต์ด้วยปุ่ม SSH ดังนั้นฉันจึงไม่ได้รับแจ้งให้ใส่รหัสผ่านเมื่อกด บทความHosting Git Repositories วิธีที่ง่าย (และปลอดภัย)จะบอกวิธีตั้งค่าทั้งหมดนั้น


1

วิธีที่ดีที่สุดในการทำเช่นนี้คือ:

mkdir ..../remote
cd ..../remote
git clone --bare .../currentrepo/

นี้จะโคลนพื้นที่เก็บข้อมูล แต่มันจะไม่ทำสำเนาการทำงานใด ๆ .../remoteใน ถ้าคุณดูที่รีโมตคุณจะเห็นหนึ่งไดเรกทอรีที่สร้างขึ้นcurrentrepo.gitซึ่งอาจเป็นสิ่งที่คุณต้องการ

จากนั้นจากที่เก็บ Git ในพื้นที่ของคุณ:

git remote add remoterepo ..../remote/currentrepo.git

หลังจากที่คุณทำการเปลี่ยนแปลงคุณสามารถ:

git push remoterepo master

1

ฉันเพียงแค่วิ่งเข้าไปในปัญหานี้กับพื้นที่เก็บข้อมูลการใช้งานคอมไพล์บนHeroku

ฉันไม่รู้ว่าทำไม Heroku ถึงมีพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยเปล่าอยู่ข้างๆ แต่ในฐานะที่เป็นวิธีแก้ปัญหาฉันสามารถรีเซ็ตที่เก็บรีโมตและรีโหลดได้

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

วิธีรีเซ็ต:

  1. ติดตั้งแถบเครื่องมือ Heroku (ซึ่งมีไคลเอ็นต์บรรทัดคำสั่ง) หากคุณยังไม่ได้ติดตั้ง
  2. ติดตั้งปลั๊กอิน heroku-repoหากคุณยังไม่ได้ติดตั้ง

    heroku plugins:install https://github.com/heroku/heroku-repo.git
    
  3. ทำการรีเซ็ตซึ่งจะลบที่เก็บและสร้างอันใหม่ที่ว่างเปล่า

    heroku repo:reset
    
  4. กดไปที่รีโมท Heroku ของคุณตามปกติ มันจะอัปโหลดทุกอย่างใหม่


คุณอาจต้องติดตั้งเครื่องมือ repo ของ Heroku เพื่อให้ทำงานได้ ทำheroku plugins:install https://github.com/heroku/heroku-repo.git
โนอาห์

1

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

root@development:/home/git/repository/my-project# cat config 

ที่นั่นคุณจะเห็น

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true

คุณจะทำให้สิ่งนี้เป็นเท็จเป็นจริงและฉันลบ logallrefupdates = จริง (ไม่แน่ใจในการใช้!)

ถึง

[core]
repositoryformatversion = 0
filemode = true
bare = true

คุณสามารถทดสอบได้ดังนี้

$ git remote show origin
* remote origin
Fetch URL: my-portal@development:/home/XYZ/repository/XYZ
Push  URL: my-portal@development:/home/XYZ/repository/XYZ
HEAD branch: (unknown)

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

git remote show origin

และคุณจะเห็น

 HEAD branch: master

0

สำหรับฉันวิธีแก้ปัญหาการทำงานคือ:

ในระยะไกล:

git checkout -b some_tmp_name

ในท้องถิ่น:

git push

ในระยะไกล:

git checkout master
git branch -d some_tmp_name

แต่นี่ไม่ใช่วิธีการแก้ปัญหาที่แท้จริงมันเป็นเพียงการแก้ปัญหา


นี่เป็นทางออกที่ถูกต้องหากคุณไม่มีที่เก็บส่วนกลาง
Rick

0

ในกรณีที่มีคนพบว่ามีประโยชน์ สำหรับฉันมันเป็นปัญหาสิทธิ์เซิร์ฟเวอร์ git ฉันเช็กเอาต์โครงการจากการเริ่มต้นและผลักดันไฟล์อย่างง่ายจากนั้นฉันได้รับ "การกดปฏิเสธ: พุชไปยังต้นทาง / มาสเตอร์ถูกปฏิเสธ"


-1

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

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

ดังนั้นนี่คือตัวอย่าง:

บนพีซีใน ~ / พื้นที่ทำงาน

git init
echo "line 1" > afile.txt
git add .
git commit -m ‘initial import’
git clone --bare . ../remote-repository.git
git remote add origin ../remote-repository.git
git push --set-upstream origin master

บนแล็ปท็อปใน ~ / พื้นที่ทำงาน (ห้าม git init ฯลฯ )

git clone //LJZ-DELLPC/remote-repository.git/ .

// จากนั้นทำคอมมิชชันต่าง ๆ แล้วผลักมัน:

echo "line 2" > afile.txt
git add afile.txt
git commit -m 'added line 2'
git push    

จากนั้นกลับสู่พีซีใน ~ / พื้นที่ทำงาน

git pull

// จากนั้นทำคอมมิชชันต่าง ๆ แล้วผลักมัน:

git push

ในการดึงคอมไพล์แล็ปท็อป

และอื่น ๆ ..

นี่คือตัวอย่างที่เป็นรูปธรรมทั้งหมดในเครื่องเดียวคัดลอกโดยตรงจากหน้าต่างคำสั่งเพื่อที่เราจะได้รู้ว่าไม่มีขั้นตอนใดถูกทิ้งไปใช้งานได้จริง ฯลฯ :

lylez@LJZ-DELLPC ~
$ cd gitdir
/home/lylez/gitdir

lylez@LJZ-DELLPC ~/gitdir
$ ls

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1
/home/lylez/gitdir/repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git init
Initialized empty Git repository in /home/lylez/gitdir/repo1/.git/

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 1" > afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'initial import'
[master (root-commit) f407e12] initial import
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git clone --bar . ../repo1-bare-clone
Cloning into bare repository '../repo1-bare-clone'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git remote add origin ../repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push --set-upstream origin master
Branch master set up to track remote branch master from origin.
Everything up-to-date

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ..

lylez@LJZ-DELLPC ~/gitdir
$ ls
repo1  repo1-bare-clone

lylez@LJZ-DELLPC ~/gitdir
$ mkdir repo1-remote

lylez@LJZ-DELLPC ~/gitdir
$ cd repo1-remote
/home/lylez/gitdir/repo1-remote

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git clone ../repo1-bare-clone .
Cloning into '.'...
done.

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ echo "line 2" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git commit -m 'added line 2'
[master 5ad31e0] added line 2
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 260 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   f407e12..5ad31e0  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cd ../repo1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../repo1-bare-clone
   f407e12..5ad31e0  master     -> origin/master
Updating f407e12..5ad31e0
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1
$ echo "line 3" >> afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git add afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git commit -m 'added line 3'
[master 3fa569e] added line 3
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1
$ git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../repo1-bare-clone
   5ad31e0..3fa569e  master -> master

lylez@LJZ-DELLPC ~/gitdir/repo1
$ cd ../repo1-remote/

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ ls
afile.txt

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git pull
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/lylez/gitdir/repo1-remote/../repo1-bare-clone
   5ad31e0..3fa569e  master     -> origin/master
Updating 5ad31e0..3fa569e
Fast-forward
 afile.txt | 1 +
 1 file changed, 1 insertion(+)

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ cat afile.txt
line 1
line 2
line 3

lylez@LJZ-DELLPC ~/gitdir/repo1-remote
$ git --version
git version 2.1.1

lylez@LJZ-DELLPC ~/gitdir/repo1-remote

มันเป็นตัวอย่างของการทำงานและคำอธิบายว่าทำไม ที่นี่ไม่มีข้อมูลที่ผิดเลยยกเว้นความคิดเห็นของคุณ
Lyle Z

1
"ด้วย Git ที่เก็บแบบธรรมดาสองที่ (ไม่เปลือย) ไม่สามารถดัน / ดึงไฟล์ไปมาได้โดยตรง" - ยกเว้นว่าพวกเขาจะทำได้
Andrew C

ดีโพสต์ตัวอย่างที่เป็นรูปธรรมแทนที่จะเป็นการโจมตี
Lyle Z

หรือคุณจะ google มันได้หรือไม่ stackoverflow.com/questions/1764380/…
แอนดรูว์ C

การตอบกลับครั้งแรกในเธรดที่ไซต์คุณเริ่มต้นด้วย "... แต่ตามคอมไพล์ git และวิกิ git อย่างเป็นทางการคุณควรผลักดันไปยัง repo ที่เปลือยเปล่า" สถานะการตอบกลับถัดไป "ถ้าคุณต้องการลองแค่กด master -> master คำสั่งนั้นก็คือ: git push origin" และนั่นก็ไม่ได้ผล การตอบกลับครั้งสุดท้ายเริ่มต้นด้วย "ฉันขอแนะนำให้มีที่เก็บเปลือยและ repos ที่ทำงานในพื้นที่ (ไม่ใช่เปลือย) ในเซิร์ฟเวอร์ของคุณ" ซึ่งเป็นสิ่งที่ฉันเสนอ
Lyle Z

-3

โซลูชันของฉัน (ใช้งานอยู่)

  1. ชำระเงิน "ต้นแบบ" บนเซิร์ฟเวอร์ระยะไกล
  2. ทำงานในสาขา "dev"
  3. พุชการเปลี่ยนแปลงเป็นรีโมต dev
  4. รวม dev เข้ากับ master บน remote

การเล่นชนิดหนึ่ง

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