Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

origin.pull(rebase=True) sometimes lost local commit , gitpyton version 3.1.31 #1863

Open
boboyunduoer opened this issue Mar 11, 2024 · 3 comments

Comments

@boboyunduoer
Copy link

boboyunduoer commented Mar 11, 2024

I had concurrent git pull/push in my deployment pipelines, sometimes git pull (rebase) only get remote commit and lost local commit (rebase seems happened)

below is the git actions in first pipeline (no issue happened)
image

below is the git actions in second pipeline which runs 1 second later than above pipeline (git pull seems lost local commit)
image

take below graph as example , we should get commit hash 4 after pull but we only get 2 (above a3324df), seems rebase action did not happened when pull?
image

do we have any way to check if git.pull success or raise exception when git.pull failed?

appreciated !!!

part of the code:

            GIT_PUSH_RETRY_NUMBER = 2
            for i in range(1, 2 + GIT_PUSH_RETRY_NUMBER):  
                try:
                    origin = self.repo.remotes.origin
                    LOG.info("🔧 Pull first before push")
                    LOG.info(f"🔧 ProductConfig commit id before pull(rebase) is {self._get_short_sha()}")
                    origin.pull(rebase=True)
                    LOG.info(f"🔧 ProductConfig commit id after pull(rebase) is {self._get_short_sha()}")
                    LOG.info("🔧 Push changes to ProductConfig master branch")
                    origin.push().raise_if_error()
                    break  # if push succeed, no need retry anymore
                except Exception as e:
                    if i > GIT_PUSH_RETRY_NUMBER:  # if number of retry reached, throw e to terminate
                        raise e
                    LOG.warn(f"🔧 Git error: {e}")
                    SLEEP_SECONDS = randint(
                        1, 20
                    )  # just use random number between 1 and 20, different pipeline will wait for different time
                    LOG.info(f"🔧 Sleep {SLEEP_SECONDS} seconds and git push retrying {i}/{GIT_PUSH_RETRY_NUMBER} ...")
                    sleep(SLEEP_SECONDS)
    def _get_short_sha(self):
        sha = self.repo.head.object.hexsha
        short_sha = self.repo.git.rev_parse(sha, short=7)
        return short_sha[0:7]
@Byron
Copy link
Member

Byron commented Mar 11, 2024

Thanks for providing all this information to help making it possible to understand the issue. I most definitely still don't follow and would believe that git pull will always do its job no matter what. Maybe GitPython fails to parse the information correctly from its output, maybe there are issues with .git/FETCH_HEAD, but that is just guesses.

I'd also expect origin.pull(…) to raise an exception if the underlying git process failed.

@boboyunduoer
Copy link
Author

boboyunduoer commented Mar 14, 2024

thanks Byron for your comments

Yes, it is really strange issue and the issue is randomly happened (not each time)
I did not check the how gitpython pull work and just expect something like raise_if_error() in push if possible, etc

thank you anyway!

@boboyunduoer
Copy link
Author

I found workround is cherry pick local commit again after pull
(also somehow related with no-fork-point/fork-point, not clear about this part), anyway, git.pull does not work as normally expected
we may close this ticket or improve git.pull to improve :-)
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants