2016-04-27 94 views
1

我正在使用GitPython從Gitlab服務器克隆存儲庫。如何使用GitPython?

git.Repo.clone_from(gitlab_ssh_URL, local_path) 

後來我有嘗試更新此回購另一個腳本。

try: 
    my_repo = git.Repo(local_path) 
    my_repo .remotes.origin.pull() 

except (git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError): 
    print("Invalid repository: {}".format(local_path) 

此,除非在中間我籤這樣的標籤偉大的工作:

tag_id = choose_tag() # Return the position of an existing tag in my_repo.tags 
my_repo .head.reference = my_repo.tags[tag_id] 
my_repo .head.reset(index=True, working_tree=True) 

在這種情況下拉動時,我得到一個GitCommandError:

git.exc.GitCommandError: 'git pull -v origin' returned with exit code 1 

我已經閱讀了兩次文檔,我不知道問題出在哪裏。尤其是因爲如果我試圖用像SourceTree這樣的專用工具來拉回這個回購,它就沒有錯誤或警告。 我不明白我是如何檢查一個標籤的版本,即使分離的頭阻止我拉。

  1. 在這種情況下我該怎麼辦?
  2. 這裏發生了什麼,我錯過了什麼?

編輯:as建議我試着查看exception.stdout和exception.sterr,這裏沒有什麼用處(分別是b和'None)。這就是爲什麼我很難理解什麼是錯的。

回答

1

我認爲最好的想法是更多地瞭解最先發生的事情(問題2:發生了什麼?),並且應該引導您回答問題1(如何解決這個問題?)。

要了解更多有關錯誤的信息,您可以從例外中打印出stdoutstderr。 Git通常在控制檯上輸出錯誤信息,所以應該在stdoutstderr

try: 
    git.Repo.clone_from(gitlab_ssh_URL, local_path) 
except git.GitCommandError as exception: 
    print(exception) 
    if exception.stdout: 
     print('!! stdout was:') 
     print(exception.stdout) 
    if exception.stderr: 
     print('!! stderr was:') 
     print(exception.stderr) 

作爲一個方面說明,我自己有一些問題幾次,當我用它來與後端交互之前做了git.Repo對象的很多操作(即git本身)。在我看來,GitPython方面有時似乎存在一些數據緩存問題,並且存儲庫(.git目錄)中的數據與git.Repo對象中的數據結構之間缺乏同步。

編輯

好吧,這個問題似乎是與拉動分離的頭 - 這可能不是你想反正做什麼。

不過,你可以解決你的問題。因爲從分離的頭部,你只做git checkout master才能做git pull,然後你回到分離的頭部,你可以跳過拉動,而改用git fetch <remote> <source>:<destination>這樣的:git fetch origin master:master。這將獲取遠程並將您的本地master分支與追蹤分支合併而不檢出,因此您可以始終保持分離的頭狀態,而不會出現任何問題。看到這個SO回答更多細節上的非常規使用獲取命令:https://stackoverflow.com/a/23941734/4973698

隨着GitPython,代碼可能是這個樣子:

my_repo = git.Repo(local_path) 
tag_id = choose_tag() # Return the position of an existing tag in my_repo.tags 
my_repo.head.reference = my_repo.tags[tag_id] 
my_repo.head.reset(index=True, working_tree=True) 
fetch_info = my_repo.remotes.origin.fetch('master:master') 
for info in fetch_info: 
    print('{} {} {}'.format(i.ref, i.old_commit, i.flags)) 

,它會打印是這樣的:

master 11249124f123a394132523513 64 

... so flags equal 64。這是什麼意思?當您執行print(git.FetchInfo.FAST_FORWARD)時,結果爲64,這意味着抓取是快進類型,因此您的本地分支已成功與遠程跟蹤分支合併,即您已執行git pull origin master而不檢出主控。

重要注意事項:只有當您的分支可以使用快進合併與遠程分支合併時,這種獲取方式纔有效。

+0

可悲的是,stderr或stdout中沒有任何東西(分別是b'和None)。我唯一得到的是異常評論:'git pull -v origin'返回退出代碼1. 這就是爲什麼我在這裏有點迷路。 我並沒有做太多,只是創建一個新的git.Repo(路徑),並試圖拉。 – Rbtnk

0

答案是,即使某個智能客戶端很好地處理這種情況,試圖拉動分離頭也不是一個好主意。 所以我在這種情況下的解決方案是簽出我的分支(主)上的最後一個版本,然後再次簽出所需的標籤版本。但是我們可以後悔GitPython給出的糟糕的錯誤信息。

+0

我用另一個可能有用的解決方法更新了我的答案。我承認在我完全錯過了脫離頭部之前。我同意,這不是一個好主意。無論如何,如果它提供了最佳解決方案,請不要忘記接受答案(即使它是你自己的答案)(https://blog.stackoverflow.com/2009/01/accept-your-own-answers/))到你的問題:) – mbdevpl