2016-04-27 6 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) 

に-の間に私はこのようなタグをチェックアウトする場合を除き、この作業素晴らしい:

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

を:引っ張ったときに、私はGitCommandErrorを取得する。この場合

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) 

は、私はすでに2回のドキュメンテーションを読んでいて、どこにプロブルムがあるのか​​分かりません。特にSourceTreeのような専用ツールでこのリポジトリを取得しようとすると、エラーや警告なしで作業しているためです。 私は、タグ付きバージョンをチェックアウトしたという事実が、分離されたHEADであっても、私が引っ張ってしまうのを防ぐ方法を理解していません。

  1. この場合、どうすればよいですか?
  2. ここで何が起こっているのですか?

編集:アドバイスとして、私はexception.stdoutとexception.sterrを調べようとしましたが、ここでは何も役に立ちません(それぞれb "とNone)。だから私は何が間違っているのかを理解するのが難しい。

答えて

1

まず、何が起こっているのかを知ることをお勧めします(質問2:何が起こっていますか?)、これは質問1の答えに導くべきです(これを修正する方法)。

何が問題になったのかを知るには、例外からstdoutstderrを印刷することができます。 gitは通常、エラーの詳細をコンソールに出力するので、何かがstdoutまたはstderrにあるはずです。サイドノートとして

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自体)と対話するためにそれを使用する前に、git.Repoオブジェクトに対して多くの操作をした数回でした。私の意見では、GitPython側でデータキャッシングに関する問題や、リポジトリ内のデータ(.gitディレクトリ)とgit.Repoオブジェクト内のデータ構造との同期の欠如があるように見えることがあります。

EDITは: - あなたはとにかく何をしたいのか、おそらくではありません

[OK]を、問題が切り離さ頭を引っ張るとのようです。

まだ、問題を回避することはできます。デタッチされたヘッドからgit checkout masterを実行するためにのみgit pullを実行してから、デタッチされたヘッドに戻ると、引っ張り飛ばしてgit fetch <remote> <source>:<destination>git fetch origin master:master)を使用することができます。これにより、ローカルのmasterブランチをトラッキングブランチとマージしてチェックアウトせずに、問題なくすべてのヘッド状態を解除することができます。これはSOコマンドをフェッチの型破りな使用の詳細については、お答えください:GitPythonでhttps://stackoverflow.com/a/23941734/4973698

を、コードは次のようになります:

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フラグは64と等しいです。どういう意味ですか? print(git.FetchInfo.FAST_FORWARD)を実行すると、結果は64になります。これは、フェッチが早送りタイプであり、ローカルブランチがリモートトラッキングブランチと正常にマージされたことを意味します。つまり、マスターをチェックアウトせずにgit pull origin masterを実行しました。

重要:この種のフェッチは、ブランチが早送りマージを使用してリモートブランチとマージできる場合にのみ機能します。

+0

悲しいことに、stderrまたはstdout(それぞれb "とNone)には何もありません。私が得る唯一のものは例外コメントです: 'git pull -v origin'は終了コード1で返されます。 それで私はここで少し失われています。 そして、私はちょっと新しいgitを作成しません。レポ(パス)とプルしようとします。 – Rbtnk

0

答えは、スマートクライアントがこのケースをうまく処理しても、デタッチヘッドを引き出そうとするのは良い考えではないということです。 この場合、私の解決策は、私の支店(マスタ)の最後のバージョンをチェックアウトし、必要なタグ付きバージョンを再度チェックアウトすることです。 しかし、私たちはGitPythonによって与えられた貧弱なエラーメッセージを後悔することができます。

+0

私は有用かもしれない別の回避策で私の答えを更新しました。私は完全に孤立した頭の上に引っ張って逃げる前にそれを認めます。それは私が同意する、それは非常に良い考えではありません。とにかく、最良のソリューションを提供する場合は、[自分の回答であっても](https://blog.stackoverflow.com/2009/01/accept-your-own-answers/)の回答を受け入れることを忘れないでくださいあなたの問題に:) – mbdevpl

関連する問題