From: Phillip Wood <phillip.wood123@gmail•com>
To: Brooke Kuhlmann <brooke@alchemists•io>, phillip.wood@dunelm•org.uk
Cc: git@vger•kernel.org, "brian m . carlson" <sandals@crustytoothpaste•net>
Subject: Re: Git Stash Synchronization - Best Workflow?
Date: Fri, 19 Sep 2025 15:04:15 +0100 [thread overview]
Message-ID: <adad093d-5129-472c-b054-fb569de9f893@gmail.com> (raw)
In-Reply-To: <E308F060-D39C-4C7A-9F38-2CA33BCE4AB2@alchemists.io>
Hi Brooke
On 11/09/2025 03:22, Brooke Kuhlmann wrote:
>
>> I'm unable to reproduce this. In the script below the final push succeeds.
>
> That's because you need to export every time before you push. Like this:
>
> touch one.txt
> git stash push --include-untracked --message "One"
>
> git stash export --to-ref "refs/stashes/$USER"
> git push --no-verify --force-with-lease --force-if-includes origin "refs/stashes/$USER"
>
> git stash pop
> git stash push --include-untracked --message "One II"
>
> git stash export --to-ref "refs/stashes/$USER"
> git push --no-verify --force-with-lease --force-if-includes origin "refs/stashes/$USER"
>
> The above will yield the following error:
>
> ! [rejected] refs/stashes/bkuhlmann -> refs/stashes/bkuhlmann (remote ref updated since checkout)
> error: failed to push some refs to 'https://github.com/bkuhlmann/test'
> hint: Updates were rejected because the tip of the remote-tracking branch has
> hint: been updated since the last checkout. If you want to integrate the
> hint: remote changes, use 'git pull' before pushing again.
> hint: See the 'Note about fast-forwards' in 'git push --help' for details.
>
> However, if you perform the above with only the single "git stash export" then you won't get the error as you discovered in your workflow.
I'm confused by this, here is the relevant part of my script again
>> git stash push
>> git stash export --to-ref refs/stashes/test
This is the first export before pushing
>> git push origin refs/stashes/test
>> git stash pop
>> git stash push -m message
>> git stash export --to-ref refs/stashes/test
This is the second export before pushing
>> git push --force-with-lease --force-if-includes origin
refs/stashes/test
I'm afraid I'm struggling to see what the difference is.
Thanks
Phillip
> The only way I've been able to make this work is to do this:
>
> touch one.txt
> git stash push --include-untracked --message "One"
>
> git stash export --to-ref "refs/stashes/$USER"
> git push --no-verify --force origin "refs/stashes/$USER"
>
> git stash pop
> git stash push --include-untracked --message "One II"
>
> git stash export --to-ref "refs/stashes/$USER"
> git push --no-verify --force origin "refs/stashes/$USER"
>
> Notice that I always export before the push AND that I'm using `--force` each time. That's the only way to ensure your local stash is in sync with the remote stash.
>
> You can always verify that the remote stash is being updated by always clearing your local stash and then immediately importing to check if your stash message was updated properly. Example:
>
> git stash clear
> git stash import "refs/stashes/$USER"
> git stash list
>
> Once you perform the import, and immediately list what's in your stash, you should see something similar to the following:
>
> stash@{0} 6ba4eaea3751 On main: One II
>
> When your remote stash isn't updated, you'll see this:
>
> stash@{0} 6ba4eaea3751 On main: One
>
> (Notice the difference between the message of "One" versus "One II")
>
>> You can force the creation of a reflog
>
> I tried that too which makes the error go away but doesn't update the remote stash at all. Example:
>
> touch one.txt
> git stash push --include-untracked --message "One"
>
> git stash export --to-ref "refs/stashes/$USER"
> git push --no-verify --force-with-lease --force-if-includes origin "refs/stashes/$USER"
>
> git stash pop
> git stash push --include-untracked --message "One II"
>
> oid=$(git rev-parse --verify refs/stashes/$USER) &&
> git update-ref -d refs/stashes/$USER &&
> git update-ref --create-reflog -m 'export stashes' refs/stashes/$USER $oid
>
> git push --no-verify --force-with-lease --force-if-includes origin "refs/stashes/$USER"
>
> The above works but if I run `git stash clear && git stash import "refs/stashes/$USER"`, I find that my local stash doesn't have the message change (still using "One" instead of "One II" which means the remote stash never got updated).
>
> Sadly, I can only seem to make this work when using a force push but would definitely be nice to not have to use a force push.
>
>>
>> set -ex
>> dir="$(mktemp -d)"
>> cd "$dir"
>> git init --bare origin
>> git init repo
>> cd repo
>> git remote add origin "file://${PWD%/*}/origin"
>> git config core.logAllRefUpdates always
>> git config remote.origin.fetch refs/stashes/*:refs/remote/origin/stashes/*
>> echo a >a
>> git add a
>> git commit -m a
>> echo b >a
>> git stash push
>> echo c >a
>> git stash push
>> git stash export --to-ref refs/stashes/test
>> git push origin refs/stashes/test
>> git stash pop
>> git stash push -m message
>> git stash export --to-ref refs/stashes/test
>> git push --force-with-lease --force-if-includes origin refs/stashes/test
>>
>>>> You need to pass the name of the ref whose reflog you want to look at,
>>>> otherwise it defaults to showing the reflog for HEAD. You should be
>>>> able to see the reflog for you exported stashes.>
>>> I gave this a try and every time I use `git reflog refs/stashes/$USER`,
>>> I always get a blank response. No errors and no output.
>> Ah, I wonder if core.logAllRefUpdates only affects the creation of new
>> refs. You can force the creation of a reflog by running
>>
>> oid=$(git rev-parse --verify refs/stashes/$USER) &&
>> git update-ref -d refs/stashes/$USER &&
>> git update-ref --create-reflog -m 'export stashes' refs/stashes/$USER $oid
>>
>> the same applies to refs/remote/stashes/origin/$USER
>>
>>>> Let's try and find why the remote update say's it rejected when it isn't
>>>> and then we can think about the best way to document pushing and
>>>> pulling exported stashes.
>> I haven't thought much about the pulling side of this. "git stash import"
>> appends to the existing stashes so I'm not sure how we'd cope with forced
>> updates - have got got any experience of handling this from your
>> experiments?
>>
>> Thanks
>>
>> Phillip
>
>
next prev parent reply other threads:[~2025-09-19 14:04 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-31 23:25 Git Stash Synchronization - Best Workflow? Brooke Kuhlmann
2025-09-01 10:10 ` Phillip Wood
2025-09-01 20:48 ` Brooke Kuhlmann
2025-09-05 14:03 ` Phillip Wood
2025-09-06 12:50 ` Brooke Kuhlmann
2025-09-10 9:52 ` Phillip Wood
2025-09-11 2:22 ` Brooke Kuhlmann
2025-09-19 14:04 ` Phillip Wood [this message]
[not found] ` <A42DC91A-91F2-4AB6-B0EE-52DE5135E99E@alchemists.io>
2025-09-19 19:54 ` Brooke Kuhlmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=adad093d-5129-472c-b054-fb569de9f893@gmail.com \
--to=phillip.wood123@gmail$(echo .)com \
--cc=brooke@alchemists$(echo .)io \
--cc=git@vger$(echo .)kernel.org \
--cc=phillip.wood@dunelm$(echo .)org.uk \
--cc=sandals@crustytoothpaste$(echo .)net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox