I work in a very large repository, but all of it except for my stashed
items can be re-downloaded from the remote URL.
Stash though is much smaller in size and is especially valuable. Its
loss would be very expensive.
Could you please consider adding 'git stash export', 'git stash import'
commands so that in case of an accidental repository loss stash can be
imported from the external backup?
Thanks,
Yuri
From: Randall S. Becker <hidden> Date: 2021-05-05 20:07:59
On May 5, 2021 3:52 PM, Yuri wrote:
Subject: [feature suggestion] Add 'git stash export', 'git stash import' commands
to allow to backup stash externally
I work in a very large repository, but all of it except for my stashed items can be
re-downloaded from the remote URL.
Stash though is much smaller in size and is especially valuable. Its
loss would be very expensive.
Could you please consider adding 'git stash export', 'git stash import'
commands so that in case of an accidental repository loss stash can be
imported from the external backup?
I would like to suggest another option: Teach clone and fetch to transfer stash commits. They are filtered out normally. It might be straightforward to preserve the stashed commits. A mirror approach is probably not appropriate since that needs the repo to be bare and Yuri's situation is unlikely to support that. So something like --include-stashes, which would be off by default.
As a side potential defect/bug, if you fetch refs/stash, git is happy to comply and reports the HEAD update and then loses it. git show-refs does not show the stash. What I saw on the fetch was (I only had untracked files in my stash to make things more painful) as follows in 2.29.1:
$ git fetch origin refs/stash
From /path-to-repo
* branch refs/stash -> FETCH_HEAD
-Randall
From: Johannes Sixt <hidden> Date: 2021-05-06 06:08:03
Am 05.05.21 um 21:51 schrieb Yuri:
I work in a very large repository, but all of it except for my stashed
items can be re-downloaded from the remote URL.
Stash though is much smaller in size and is especially valuable. Its
loss would be very expensive.
I would argue that you are doing something wrong if your stashes are
particularly valuable. If you regularly revert temporary, but precious
work, then you should commit the work and mark it with a branch tip or tag.
Could you please consider adding 'git stash export', 'git stash import'
commands so that in case of an accidental repository loss stash can be
imported from the external backup?
I would argue that you are doing something wrong if your stashes are
particularly valuable. If you regularly revert temporary, but precious
work, then you should commit the work and mark it with a branch tip or tag.
No, it is work in progress. I begin to work on some modification or
update, discover some issue, and stash the update until this issue is
resolved,
It could take days, weeks, months to resolve them.
Yuri
From: Johannes Sixt <hidden> Date: 2021-05-06 06:44:02
Am 06.05.21 um 08:12 schrieb Yuri:
On 5/5/21 11:07 PM, Johannes Sixt wrote:
quoted
I would argue that you are doing something wrong if your stashes are
particularly valuable. If you regularly revert temporary, but precious
work, then you should commit the work and mark it with a branch tip or
tag.
No, it is work in progress. I begin to work on some modification or
update, discover some issue, and stash the update until this issue is
resolved,
It could take days, weeks, months to resolve them.
I know. But, as I said, when you turn away from your current work, which
is precious, then you should make a commit, in particular, when you can
forsee that you might not be able to come back soon.
A 'git stash' is really only intended as a short-term
make-the-worktree-temporarily-clean auxiliary storage. It is not
intended as a long-term storage. For long-term storage, use branches.
"Short term" is measured in seconds (rebase --autostash), minutes,
perhaps hours, but certainly not weeks or months.
At least, that's how I understand (and use) it.
-- Hannes
I know. But, as I said, when you turn away from your current work, which
is precious, then you should make a commit, in particular, when you can
forsee that you might not be able to come back soon.
How can I commit unfinished work? Commits are public, this would break
things.
For long-term storage, use branches.
Branches are too heavy-weight. They need merging. Sometimes several stash items need to be used together, which makes it inconvenient.
Yuri
From: Felipe Contreras <hidden> Date: 2021-05-06 08:40:16
Yuri wrote:
On 5/5/21 11:43 PM, Johannes Sixt wrote:
quoted
I know. But, as I said, when you turn away from your current work, which
is precious, then you should make a commit, in particular, when you can
forsee that you might not be able to come back soon.
How can I commit unfinished work?
Just like that: `git commit`.
That's what you are doing anyway, whether you realize or not.
Commits are public, this would break things.
No. Commits are most definitely not public. Not unless you do
`git push`, and only if you push to a public repository.
I have countless commits on local branches that nobody would every see.
Many on a "tmp" branch.
I also have many private repositories, which contain passwords and other
sensitive information. Again... Only for my eyes.
quoted
For long-term storage, use branches.
Branches are too heavy-weight.
No, each one is a single file consisting of 41 bytes.
A single stash takes about 200 bytes. Considerably more.
Compare:
* .git/refs/heads/master
* .git/logs/refs/stash
They need merging. Sometimes several stash items need to be used
together, which makes it inconvenient.
You mean like one stash item goes on top of another?
Like... Commits on a branch?
I think this boils down to a confussion of concepts. Stash items are
commits. The only real conceptual difference is that you did not
specify the message (-m tmp would do that trick).
Again. Check yourself; the commit is there:
* git cat-file -p stash@{0}
* git cat-file -p master
Cheers.
--
Felipe Contreras
No. Commits are most definitely not public. Not unless you do
`git push`, and only if you push to a public repository.
I have countless commits on local branches that nobody would every see.
Many on a "tmp" branch.
So you advocate to use branches? If branches are same or better than
stash, why was the stash feature created?
Maybe it should be removed in favor of branches?
Yuri
From: Felipe Contreras <hidden> Date: 2021-05-06 10:45:14
Yuri wrote:
On 5/6/21 1:40 AM, Felipe Contreras wrote:
quoted
No. Commits are most definitely not public. Not unless you do
`git push`, and only if you push to a public repository.
I have countless commits on local branches that nobody would every see.
Many on a "tmp" branch.
So you advocate to use branches? If branches are same or better than
stash, why was the stash feature created?
Branches are for long-term sequences of useful commits.
Stashes are for short-term crappy commits.
They serve a different purpose.
--
Felipe Contreras
On Thu, May 06, 2021 at 01:45:41AM -0700, Yuri wrote:
So you advocate to use branches? If branches are same or better than stash,
why was the stash feature created?
Maybe it should be removed in favor of branches?
Stash is actually *implemented* in terms of a branch and reflogs.
It's syntactic sugar --- a user interface --- for a simple use case,
which is designed for use by users who don't care to learn a richer,
more complex set of commands, or who want to use for simple, temporary
use cases.
So you can see the top-most stash by running the command:
git log refs/stash
You can also see that these two commands produce essentially the same
output:
git stash list
git reflog refs/stash
By the way, reflogs by default expire after 90 days. And if you do
something like this:
git reflog expire --expire=now --all
git stash list
*Poof* Watch all of your stashed patches disappear. So if you are
storing things that you consider especially valuable using git stash,
I'd encourage you to rethink your strategy.
For anything that needs to be saved more than a few minutes, I tend to
create explicit branches, which can be named, so it's obvious is going
on. Those branches aren't pushed out publically by default, any more
than the branch refs/stash is pushed out publically. But because they
are branches, you can push them out explicitly, perhaps to a private
remote repo, if you like.
You can then use git cherry-pick, git rebase, git rebase -i, git
commit --amend, etc., to manage your work in progress. This gives
much finer-grained control over how you manage your in-progress work,
at the cost of needing to learn a more complex set of commands.
Cheers,
- Ted
P.S. One hint: if the reason why you don't like using explicit branches is
because you get confused what branch you are on, it's helpful to put
your current branch on shell prompt. I do something like this:
<tytso@cwcc> {/usr/projects/e2fsprogs/e2fsprogs} (next)
1822% git checkout tt/pfsck
Switched to branch 'tt/pfsck'
<tytso@cwcc> {/usr/projects/e2fsprogs/e2fsprogs} (tt/pfsck)
1823%
One of the conventions I use is that [initials]/* for branch names
that are generally never pushed out. "tt" is my own initials, for my
own work. Other people's initials are used for when they send me
branches to look at, that aren't quite ready to be merged into the
master, next, or maint branches. Sometimes I will follow Junio's
convention of merging other people's in-progress work that they've
sent me into a pu (proposed updates) branch, for other people to test
and review, and for integration testing. I tend not to do that often
since e2fsprogs' development tends not to be as complex/dynamic as
git's.
My shell prompt is accomplished through this in my .bashrc:
if [ $UID = 0 ]; then
u="${LOGNAME}.root"
p="#"
else
u="$LOGNAME";
p="%"
fi
if [ $SHLVL != 1 ]; then
s=", level $SHLVL"
fi
h=${HOSTNAME}
if [ -n "$debian_chroot" ]; then
h=${debian_chroot}-CHROOT.${h}
fi
if test -f /etc/bash_completion ; then
. /etc/bash_completion
fi
if test -f /usr/local/share/bash-completion/bash_completion.sh ; then
. /usr/local/share/bash-completion/bash_completion.sh
fi
if test -f /usr/local/share/git-core/contrib/completion/git-prompt.sh ; then
. /usr/local/share/git-core/contrib/completion/git-prompt.sh
fi
if type __git_ps1 >& /dev/null ; then
PS1="<${u}@${h}> {\${PWD}}$s \$(__git_ps1)\n\!$p "
else
PS1="<${u}@${h}> {\${PWD}}$s\n\!$p "
fi
unset u s h