2010-11-05 89 views
22

我一直在試圖找出這一個,但我很難做到這一點。我目前正在開發一個開源項目,要求我允許用戶將到遠程存儲庫而不是它已經存在那裏。我想避免手動登錄到服務器並運行git initgit init --bareGit在推送時創建遠程存儲庫

出於顯而易見的原因,我想我的本地庫推到不指向現有資源庫的遠程服務器上的路徑時,遇到下列錯誤:

fatal: '/var/repositories/myrepo' does not appear to be a git repository 
fatal: The remote end hung up unexpectedly 

但我想是能夠例如運行以下命令:

git push origin master 

而且具有在/var/repositories創建/myrepo如果它不存在。我將如何能夠做到這一點?我會認爲它是某種(全局)git config設置你可能會設置在遠程服務器上,或者在本地設置爲(存儲庫特定)git config,但我無法弄清楚。

任何幫助將不勝感激!

謝謝!

回答

6
  1. 結帳並跟蹤從遠程分支:

    git checkout -t origin\funbranch 
    
  2. 分公司關閉它:

    git checkout -b mybranch 
    
  3. 把你的新一輪上漲,它會創建一個新的分支自動在遙控器上:

    git push origin mybranch 
    

應該說「創造了新的遠程分支來源\ mybranch」

如果你仍然得到「遠程端掛機」,這聽起來像一個安全的事情。您是否正確安裝了SSH密鑰,並且您是否具有遠程服務器上的寫入權限?

大多數開源項目的工作方式是,您必須創建一個用於完成工作的叉(克隆本身),因爲大多數時候您沒有對該倉庫的寫入權限。當你有變化時,你將發送一個拉取請求給資源庫所有者,他/她將從你的分支中提取他們想要的變化。

+1

嗨。謝謝回覆!儘管對於大多數觀看這個問題的人來說這是一個有效的答案,但它並不是我正在尋找的那個。我需要能夠推動我的本地__develop__分支,例如遠程__staging__分支。但我不想創建一個新的分支來完成跟蹤和所有。你知不知道這可能是可以實現的,而無需對本地存儲庫進行更改?對不起,如果問題有點不清楚,我想要做的可能不是很常見。 :) – 2010-11-05 15:55:49

+5

@Michael:你的評論在這裏聽起來根本不像你的問題。在這裏你正在談論推送一個本地分支到不同的遠程分支(可能存在也可能不存在)。然而,你的問題是關於推送到* repository *尚不存在的遠程,並且必須創建。 – Cascabel 2010-11-05 17:49:11

22

目前無法使用git push在遠程創建存儲庫。你可以做的最好的事情是寫一個這樣的腳本:

#!/bin/bash 
ssh $1 "git init --bare $2" && 
git push ssh://$1/$2 

希望你可以ssh進入;如果你不能,你可以使用某種類型的文件系統訪問來通過在適當的文件/目錄結構中轉儲(可能在本地創建並複製)手動創建回購。你也可以創建一個命名的遠程。

這實際上是2010年Git調查中最爲requested features之一 - 所以也許你會在明年的某個時候得到你的願望!

+0

感謝您的回覆,並對我遲到的回覆感到抱歉。你所說的應該確實有效。是的,我有SSH的能力。我實際上使用GitHub上的PushAnd庫解決了這個問題。我不完全確定它爲什麼可以與這個庫安裝,但它確實!我相信它會安裝一個post-push hook /腳本,它運行一些命令來初始化一個存儲庫等。 – 2010-11-19 05:57:23

+0

爲了避免兩行中的&&,爲什麼不使用'bash -e'?你也可以運行'git init --bare/path/to/$ 2'。 – Eric 2017-07-29 17:33:14

+0

@Eric這只是一個例子,但我通常更喜歡明確的錯誤處理(不必擔心bash會做什麼,不允許使用-e),並且能夠調整,複製粘貼到其他腳本中,以及所以不用擔心改變行爲。 – Cascabel 2017-07-29 18:11:50

2

我知道這是一個古老的問題,但我偶然發現了這個問題,同時用其他的東西搜索。

我發現能夠推送到遠程服務器並讓它創建存儲庫(如果它不存在)的最佳方式是使用gitolite。查看它的安裝指南,它很容易設置,如果你改變一些配置設置,你可以使用你的退出/ var/repositories來存儲回購站。

7

您可以在遠程編寫一個包裝腳本,並在authorization_keys的行前加上command =「/ path/to/wrapper」。

command="/usr/local/bin/gitaccess" ssh-rsa ... 

在這個包裝中,您將檢查SSH_ORIGINAL_COMMAND。混帳發出以下命令:

git receive-pack '/path/provided' # when pushing 
git upload-pack '/path/provided' # when pulling 

如果SSH_ORIGINAL_COMMAND不爲空,並用其中的一個開始,你檢查路徑,如有必要,創建存儲庫,安裝你需要它的任何配置,並執行命令。

如果SSH_ORIGINAL_COMMAND爲空,並且您想爲用戶提供shell訪問權限,那麼您將調用一個shell。

如果SSH_ORIGINAL_COMMAND不爲空,但不以git命令開始,如果要允許用戶擁有shell訪問權限,只需執行提供的命令即可。

這裏有一些Ruby代碼來演示。請注意,我沒有測試它,還有改進的空間(例如,我們不應該硬編碼/ bin/bash)。

#!/usr/bin/env ruby 
orig_command = ENV['SSH_ORIGINAL_COMMAND'] 
if orig_command.nil? 
    # If you want to preserve shell access 
    exec '/bin/bash' # not tested, I hope it's interactive if executed this way 
end 

cmd_parts = orig_command.match /([a-z-]+) '([a-z0-9.\/]+)'/ 
if cmd_parts.nil? 
    # If you want to preserve shell access 
    exec '/bin/bash', '-c', orig_command 
end 

command = cmd_parts[1] 
path = '/var/repositories/'+cmd_parts[2] # not secured (could contain '..') 

if command == 'git-receive-pack' || command == 'git-upload-pack' 
    if not File.directory?(path) 
     `git init --bare #{path}` # not secured, I didn't escape path 
     # Do any configuration here 
    end 
    exec 'git-shell', '-c', "#{command} '#{path}'" 
end 

# If you want to preserve shell access 
exec '/bin/bash', '-c', orig_command 

你也可以傳遞參數給這個腳本在authorized_keys中來識別用戶,並選擇他們是否應該有shell訪問。我也這樣做來控制每個存儲庫的訪問。如果你想將這個參數傳遞給git鉤子,只需創建一個環境變量。

+0

這個答案應該被投票了。我沒有嘗試過,但這是合理的。 – septianw 2015-04-27 03:34:07

相關問題