-
Notifications
You must be signed in to change notification settings - Fork 653
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
GitVersion has a bug, your HEAD has moved after repo normalisation. #1627
Comments
To clarify: The above means that a |
In my experience, GitVersion does not like working with a detached head. I'm running into a similar problem, but I've managed to work around it in some cases by running a pre-build script that will update the ref of the relevant branch to the relevant commit and check it out, but then, during normalization, GitVersion will sometimes undo this because it doesn't match the remote ref. (For whatever reason, updating the remote ref doesn't seem to fix this either, even with fetching disabled.) |
This issue has been automatically marked as stale because it has not had recent activity. After 30 days from now, it will be closed if no further activity occurs. Thank you for your contributions. |
Using gitversion inside jenkins with automatic builds I ran into this quite often. For regular branches some 'git update-ref' magic helped prior to running gitversion. I am still struggling for way to get it done for pull-requests, which are intentionally merged onto the target branch on the jenkins-ci for testing, |
This is hitting us consistently and prevents us from using GitVersion in Jenkins on a linux agent via a docker image |
here is a snippet from my jenkins lib that seems to work, creating local branches from remote branches prior to starting gitversion did help me greatly
full function:
|
Haha, @pniederlag just pipped me to the post 😄 My snippet is a little longer but should hopefully cover all bases. I had the same problem. Here's our setup:
Customisations to GitFlow (ignore if you don't have any)We have a couple of small modifications to our GitFlow process (stable instead of master, dev instead of develop). This doesn't make a real difference to the process but just so you know why stable and dev turn up in the snippet below. Just in case you have customisations, these need to be added to a $ cat GitVersion.yml
mode: ContinuousDelivery
branches:
master:
regex: (stable|master)$
ignore:
sha: [] The GitVersion Execution BlockWe use kubernetes slaves and have the gitversion docker as a side-car container. You can replace the container('gitversion') {
// 2 lines below are for debug purposes - uncomment if needed
// sh 'dotnet /app/GitVersion.dll || true'
// input 'wait'
sh 'dotnet /app/GitVersion.dll'
sh 'dotnet /app/GitVersion.dll > version.json'
} part with your chosen Which pitfalls is this snippet trying to cover.
The SnippetFinally 😉 Let me know if anything is unclear. I will edit this comment accordingly if needed. def processGitVersion() {
// special case if (a) it's a PR and (b) Merge commit
// then we need to allow IGNORE_NORMALISATION_GIT_HEAD_MOVE = 1
env.IGNORE_NORMALISATION_GIT_HEAD_MOVE = sh(
returnStdout: true,
script: '''
# if on a PR
if git config --local --get-all remote.origin.fetch | grep -q refs\\/pull; then
# if is merge commit (i.e. has more than 1 parent)
if [ $(git show -s --pretty=%p HEAD | wc -w) -gt 1 ]; then
echo -n 1
else
echo -n 0
fi
else
echo -n 0
fi
'''
)
// Determine the current checkout (branch vs merge commit with detached head)
env.ORIGINAL_CHECKOUT = sh(
returnStdout: true,
script: 'git symbolic-ref HEAD &> /dev/null && echo -n $BRANCH_NAME || echo -n $(git rev-parse --verify HEAD)'
)
// Fetch CHANGE_TARGET and CHANGE_BRANCH if env vars exist (They are set on PR builds)
sh '[ -z $CHANGE_BRANCH ] || git fetch origin $CHANGE_BRANCH:$CHANGE_BRANCH'
sh '[ -z $CHANGE_TARGET ] || git fetch origin $CHANGE_TARGET:$CHANGE_TARGET'
// Fetch default default branches needed for gitversion using gitflow.
// NOTE: only fetch if the branch does not exist locally.
// These are things like master or stable, develop or dev, release-* etc
sh '''
for b in $(git ls-remote --quiet --heads origin stable master dev develop release-* hotfix-* | sed "s:.*/::g"); do
git rev-parse -q --verify $b > /dev/null && echo "Branch $b exists locally" || git fetch origin $b:$b
done
'''
sh 'for b in $(git ls-remote --quiet --heads origin stable master dev develop release-* hotfix-* | sed "s:.*/::g"); do git fetch origin $b:$b; done'
// Checkout aforementioned branches adding any previously existing branches to the EXISTING_BRANCHES file.
sh '''
touch EXISTING_BRANCHES
for r in $(git branch -a | grep -E "remotes/origin/(stable|master|dev|develop|release-.*|hotfix-*|PR-.*)"); do
echo "Remote branch: $r"
rr="$(echo $r | cut -d/ -f 3)";
{
git checkout $rr 2>/dev/null && echo $rr >> EXISTING_BRANCHES || git checkout -f -b "$rr" $r
}
done
cat EXISTING_BRANCHES
'''
// -------------------------------------------
// **EDIT:** this has been solved by optionally setting the IGNORE_NORMALISATION_GIT_HEAD_MOVE when necessary (see above)
// So instead of checking out BRANCH_NAME, we whatever ORIGINAL_CHECKOUT was.
// -------------------------------------------
// -------------------------------------------
// Checkout the actual branch under test.
// -------------------------------------------
// If you were to keep the detached head checked out you will see an error
// similar to:
// "GitVersion has a bug, your HEAD has moved after repo normalisation."
//
// See: https://github.com/GitTools/GitVersion/issues/1627
//
// The version is not so relevant in a PR so we decided to just use the branch
// under test.
sh "git checkout $ORIGINAL_CHECKOUT"
container('gitversion') {
// 2 lines below are for debug purposes - uncomment if needed
// sh 'dotnet /app/GitVersion.dll || true'
// input 'wait'
sh 'dotnet /app/GitVersion.dll'
sh 'dotnet /app/GitVersion.dll > version.json'
}
// re checkout because gitversion messes around with something causing a
// error: failed to unmarshal /home/jenkins/workspace/proj1/.git/config due to failed to
// unmarshal /home/jenkins/workspace/proj1/.git/config due to branch config: invalid merge
sh "git checkout $ORIGINAL_CHECKOUT"
// Clean up - delete local branches checked out previously, leaving any EXISTING_BRANCHES
sh '''
git branch | grep -v HEAD
for r in $(git branch | grep -v $(git rev-parse --abbrev-ref HEAD)); do
grep -E "^${r}$" EXISTING_BRANCHES && echo "Not deleting exsting branch '$r'." || git branch -D "$r"
done
'''
// git reset hard to revert any changes
sh 'git reset --hard'
} |
This issue has been automatically marked as stale because it has not had recent activity. After 30 days from now, it will be closed if no further activity occurs. Thank you for your contributions. |
We are getting this a LOT on Teamcity. First I thought it might be just for history builds (where the tip of branch has moved on the remote) as is described in the initial issue post. But I have seen several occasions of this exception happening on one agent for the most recent main-commit (tip) and not happening on most other agents for the exact same commit which was always the tip of main. So the question for me is how to tackle and track down the bug since it is becoming a huge problem in our build pipeline. We could narrow down what causes the bug in the repo normalisation by checking for the commit-hash after each and every step during the normalisation. This would be for troubleshooting only and should be implemented so that it does not break any other behavior. What are your thoughts on that? Would you accept such a PR? |
@rominator1983 please create a PR and there we can check and discuss |
i do now see that it might very well be that the handling in finally could hide another Exception. I will therefore remove the finally block |
i had to add a nuget.config to be able to restore on my machine. i won't add that change though |
there you go |
the build errors look like they are not related to my changes. dont know, how you deal with this stuff |
just been thinking. it would also be possible after repo normalisation to explicitly checkout the requested commit. of course this behavior would have to be controlled by another environment variable. what do you think? |
I think repository normalization is something we would want to remove from GitVersion, or at least move out to a separate part of it that has to be executed explicitly, rather than the implicit execution it is implemented with as of now. I'm therefore not keen on introducing more environment variables or arguments that are related to normalization. |
I see. I don't really know, what this is for really. It seems to be working in most cases. Unfortunately the failure rate I see is too much for build-environments. |
…tionForNormalisationBug Adds trouble shooting info for #1627
just updated from 5.10 to 5.12 and still seeing this problem. btw i absolutely love this versioning program! running on jenkins, and because my jenkins refuses to properly handle tagged builds, (cant figure out why) i do
btw i'm aware of the and another annoying condition with my repos is my team USED TO cherry pick everything from release -> master so all my release branches never formally merge into master atm. This was because somebody couldnt figure out how to make Jenkinsfile work per branch and hardcoded a bunch of magic release numbers (which gitversion gets rid of) |
I have this issue in GitLab, whenever I build a pipeline of an older commit (or while a commit is being made, before gitversion is executed) - this is because GitLab checks out the Commit itself and leaves it therefore detached (unless the commit is the actual HEAD) EDIT: - git switch $CI_COMMIT_REF_NAME
- git pull
- git reset --hard $CI_COMMIT_SHA and also added the argument |
We have a peculiar issue that keeps happening on one specific commit, that is not at the tip of our branch. The latest commit in this branch does not exhibit the issue (so we're past it). I'm creating this issue because it might show some other problem you guys have (and because the exception told me to).
Output of
git log --graph --format="%h %cr %d" --decorate --date=relative --all --remotes=* -n 100
: git-152228.txtThe text was updated successfully, but these errors were encountered: