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

Stuck on push after pushed to another remote url: "There are new changes upstream, you need to pull first." #598

Open
jcalfee opened this issue Sep 25, 2023 · 4 comments
Assignees

Comments

@jcalfee
Copy link

jcalfee commented Sep 25, 2023

I recently successfully pushed this subrepo to a different remote url ("$prod"). Now I'm trying to come back to the original URL ("$origin") and push there to update that repository as well.

# This is what I need to do:
$ git subrepo push --remote=$origin $repo
git-subrepo: There are new changes upstream, you need to pull first.

# Just to show the details:
$ git subrepo pull --remote=$origin $repo
git-subrepo: Local repository does not contain de7e6f8f329b649a1049c8578cf89bee3744bbc1. Try to 'git subrepo fetch $repo' or add the '-F' flag to always fetch the latest content.

# Because the last push was $prod, the local repo **does** contain the commit changes, but the hash is different.
# In other words: $origin does not have this hash, but $prod does.  So, attempting to pull from $prod seams to work:
$ git subrepo pull --remote=$prod $repo
Subrepo '$repo' is up to date.
$ git subrepo fetch --remote=$prod $repo
Fetched '$repo' from '$prod' (master).

# Just for good measure:
$ git subrepo pull --remote=$origin $repo
git-subrepo: Local repository does not contain de7e6f8f329b649a1049c8578cf89bee3744bbc1. Try to 'git subrepo fetch $repo' or add the '-F' flag to always fetch the latest content.
$ git subrepo fetch --remote=$origin $repo
Fetched '$repo' from '$origin' (master).

# And I'll retry the desired command:
$ git subrepo push --remote=$origin $repo
git-subrepo: There are new changes upstream, you need to pull first.

I did push to a different remote and now I'm coming back to the original upstream. The default method is rebase. Possibly related #541 (comment), but I did not do any cherry picking or force push and clean did not change anything.

@jcalfee
Copy link
Author

jcalfee commented Sep 28, 2023

I already tried the -F above (fetch). Why does force push not disable this check? ("Local repository does not contain de7e6f8")

$ git subrepo push $repo -r "$origin" --force
git-subrepo: Local repository does not contain de7e6f8f329b649a1049c8578cf89bee3744bbc1. Try to 'git subrepo fetch $repo' or add the '-F' flag to always fetch the latest content.

If I can't save it, I believe I recall correctly: I can delete $repo/.gitrepo, commit that delete, then use git subrepo init to recreate the repo and push it to the correct place, then not try this again.

@admorgan
Copy link
Collaborator

The create a commit on push is feeling more like an anit-feature to me. The reason it behaves that way makes sense, it makes future operations faster, but I use a lot of services such as Gerrit where the pushed patch doesn't just go into a repo, it gets reviewed and updated so it doesn't contain the same SHA. This breaks the interaction. Also doing a git subrepo pull after a push would accomplish the same goal. I have been sitting on it because it is a big change to how things work. I think your use case makes my case stronger. I will make a patch for removing the push commit to the next released version.

@admorgan admorgan self-assigned this Oct 11, 2023
@mathrick
Copy link

Any news on this, or better yet, a workaround for now? I ran into the same issue, and I'm 100% stuck with no way forward that I can see. My use-case is the following:

  • Working on my main project, I need an external dependency, but I also need to make some changes to the dep to fit my needs
  • I fork the dependency, and include the fork (by github url) as a subrepo in the main project
  • As I work on the main project, I make changes to the external dep as needed. Within the main history, they're linear and stacked on top of each other
  • I also have a local checkout of my fork on the same machine as my main project, to make it easier to do the integration work, because I'm trying to split the big pile of commits as it exists in the main project into a series of independent branches that can be individually submitted upstream to the maintainer of the external dep. The idea here is that I push into the local repo, do some rebasing mumbo-jumbo to make it look like those were independent branches from the start, then make my fork's master into an integration branch that merges them all that I can then merge from / rebase onto in my subrepo

Now where the wheels came off the cart seems to be some combination of me pushing to my fork's github URL first, before creating an intermediary local repo and pushing/pulling from there, together with some of the branch manipulation it seems. I don't know exactly when it got hosed, but the end result is that I'm now completely stuck with subrepo.commit pointing to a commit that's not in the ancestry chain, which breaks all the commands I try, and no way forward, because it looks at subrepo.commit SHA as it existed back in the listed subrepo.parent, rather than as it exists in the current HEAD, so I have no way to try to convince it to use a commit that actually does exist in the ancestry.

The only way I can see is to rewrite my published history on the main project to fixup the original subrepo.parent to point to the replacement subprepo.commit SHA, then change the value of subrepo.parent SHA in the HEAD to let it resolve stuff. But that's many commits back in history, that history has been pushed already, it feels awful that I have to compromise main's history to unhose the subrepo, and I'm not even sure it won't get me into another circular pickle by rebasing the ancestry and potentially invalidating the replacement subrepo.commit SHA in the process. All in all, not a great experience.

@mathrick
Copy link

Also, I'd like to point out that the message it gives is terribly unhelpful and not at all what the issue is. The line in question checks for ancestry, but no amount of fetching from the remote will change the ancestry, unless I'm missing something very fundamental about how git subrepo operates. So suggesting git subrepo fetch or -F is only making things more confusing.

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

No branches or pull requests

3 participants