Message ID | 20220310173236.4165310-1-sandals@crustytoothpaste.net (mailing list archive) |
---|---|
Headers | show |
Series | Importing and exporting stashes to refs | expand |
"brian m. carlson" <sandals@crustytoothpaste.net> writes: > ... The commits used in a stash export are nearly > identical to those used in the stashes, with one notable change: the > first parent of a stash is a pointer to the previous stash, or an empty > commit if there is no previous stash. All of the other parents used in > the stash commit are present following it in their normal order. > ... > We intentionally attempt to exactly round-trip commits between stashes, > although we don't do so for the exported data due to the base commit not > having identical timestamps. Preserving the commits exactly lets us > more efficiently test our code and it also permits users to more easily > determine if they have the same data. Hmph, out of reflog entries stash@{0}, stash@{1}, stash@{3}, if we create a chain of commits A, B, C such that A^2 = B, A^1 = stash@{0} B^2 = C, B^1 = stash@{1} C^1 = stash@{2} then the original stash entry commits can be recreated identically, and after you export the stash as "A", you can "import" from it without creating any new commit to represent the stash entries, no? When we create A, if we use a predictable commit log message and the same author/committer ident as A^1 (i.e. stash@{0}), and do it the same for B and C, then no matter who exports the stash and at which time, we'd get an identical result, I would presume. > The tooling here is intentionally plumbing. It's designed to be simple > and functional and get the basic job done. If we want additional > features, we can add them in the future, but this should be a simple, > basic feature set that can support additional uses. Sounds sensible.
On 2022-03-10 at 19:14:59, Junio C Hamano wrote: > "brian m. carlson" <sandals@crustytoothpaste.net> writes: > > > ... The commits used in a stash export are nearly > > identical to those used in the stashes, with one notable change: the > > first parent of a stash is a pointer to the previous stash, or an empty > > commit if there is no previous stash. All of the other parents used in > > the stash commit are present following it in their normal order. > > ... > > We intentionally attempt to exactly round-trip commits between stashes, > > although we don't do so for the exported data due to the base commit not > > having identical timestamps. Preserving the commits exactly lets us > > more efficiently test our code and it also permits users to more easily > > determine if they have the same data. > > Hmph, out of reflog entries stash@{0}, stash@{1}, stash@{3}, if we > create a chain of commits A, B, C such that > > A^2 = B, A^1 = stash@{0} > B^2 = C, B^1 = stash@{1} > C^1 = stash@{2} > > then the original stash entry commits can be recreated identically, > and after you export the stash as "A", you can "import" from it > without creating any new commit to represent the stash entries, no? True, that's an alternative approach. Mine has the nice ability that you can see the items in the stash with log --first-parent, which I found to be useful in my testing. We could of course change yours to have that property as well by reversing the order, but then the last item in the chain would have a base commit or a different pattern. Yours does have the nice ability that we can see the actual original stash commits as well. > When we create A, if we use a predictable commit log message and > the same author/committer ident as A^1 (i.e. stash@{0}), and do it > the same for B and C, then no matter who exports the stash and at > which time, we'd get an identical result, I would presume. True. I do want to preserve my nice --first-parent property. What I propose to do is this: I'll take your approach and reverse the parents to preserve the --first-parent chain and synthesize a predictable root commit based on the fake ID information we use for stashes when nobody's provided any.
"brian m. carlson" <sandals@crustytoothpaste.net> writes: > I do want to preserve my nice --first-parent property. What I propose > to do is this: I'll take your approach and reverse the parents to > preserve the --first-parent chain and synthesize a predictable root > commit based on the fake ID information we use for stashes when nobody's > provided any. I am wondering if this can be made not an export format but a new mechanism to store stashes that we use without having to export and import. Capping the series of "stash entry" commits with an extra commit that is continuously amended, and recording which stash entry has already been used (and not to be shown) etc., in the log message part of that commit, would give us "stash drop" without rewriting all the history and would easily bring us to feature parity with the reflog based implementation, I would hope?
On 2022-03-10 at 21:38:42, Junio C Hamano wrote: > "brian m. carlson" <sandals@crustytoothpaste.net> writes: > > > I do want to preserve my nice --first-parent property. What I propose > > to do is this: I'll take your approach and reverse the parents to > > preserve the --first-parent chain and synthesize a predictable root > > commit based on the fake ID information we use for stashes when nobody's > > provided any. > > I am wondering if this can be made not an export format but a new > mechanism to store stashes that we use without having to export and > import. Capping the series of "stash entry" commits with an extra > commit that is continuously amended, and recording which stash entry > has already been used (and not to be shown) etc., in the log message > part of that commit, would give us "stash drop" without rewriting > all the history and would easily bring us to feature parity with the > reflog based implementation, I would hope? I had thought of providing a different stash format via extensions.stashFormat or something instead of this. The problem becomes backward compatibility: we essentially can't use stashes with older versions, and a very common use case in development is to work inside a Docker container or such where the version of Git is whatever the OS happened to ship, so such a change can be painful. It also impedes working with the repository using libgit2, which is heavily used in some environments (e.g., the Rust toolchain), until someone ports that change there. I'm not opposed to seeing such a format change where refs/stash itself becomes pushable via a format change, but for my present use case, I don't want to do that right now. It's possible that I might write such a series in the future, or someone else could write it, but I won't be writing it at the present moment.