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

Improve "how to recover" experience #4

Open
tkellogg opened this issue Jan 3, 2022 · 4 comments
Open

Improve "how to recover" experience #4

tkellogg opened this issue Jan 3, 2022 · 4 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@tkellogg
Copy link
Owner

tkellogg commented Jan 3, 2022

The readme outlines how to use a dura branch to recover, but it involves a lot of git-fu. It could be a lot easier

Idea: sub-commands

Add dura subcommands to do things like

  • Get the branch corresponding to HEAD, e.g. dura head
  • Get a commit by time frame, e.g. dura head 4h. I imagine this searching across dura branches, since we can indeed go prior to the HEAD commit.
  • Recover to a specific commit hash (or a time frame).

Idea: Add help messages in relevant places

Documentation in the readme is great, but it could be better if we added help directly into messages that dura has to leave anyway. For example, why not set the commit message to something like:

dura auto-backup

To recover to this commit, run this:

<<git commands>>
@tkellogg tkellogg added enhancement New feature or request good first issue Good for newcomers labels Jan 3, 2022
@kerneis
Copy link
Contributor

kerneis commented Jan 3, 2022

Using a recent-enough git version, you can use https://git-scm.com/docs/git-restore, and combine this with some git rev-list magic to automatically get the latest snapshot from eg. 1 hour ago, and even restrict to some files only. Stuff it all in a git alias, and here is your magic:

# You need to do this only once and for all
git config --global alias.dura '!restore () { local when="$1"; shift; cd "$GIT_PREFIX"; git restore --worktree --staged --source $(git rev-list -n 1 dura-$(git rev-parse HEAD) --until "$when") ${@:-:/} ; }; restore'
# Then in your repo you can restore things like they were 1 hour ago:
git dura 1hour
# Or longer:
git dura 2month
# You can also give an exact date:
git dura 2021-03-04
# And restrict to some files (any git pathspec will work here):
git dura 15min README 'src/*.c'

Note that by default it will restore all the files in your repository, even if you are in a subdirectory (that's the magic part done by ${@:-:/}).

@kerneis
Copy link
Contributor

kerneis commented Jan 3, 2022

As it turns out, you don't even need git restore, using --staged --worktree is equivalent to git checkout hence:

git config --global alias.dura '!restore () { local when="$1"; shift; cd "$GIT_PREFIX"; git checkout $(git rev-list -n 1 dura-$(git rev-parse HEAD) --until "$when") -- ${@:-:/} ; }; restore'

The alias will fail if you don't provide a date, which is working as intended (but the error message is confusing, let me know if you want error handling for it).

@kerneis
Copy link
Contributor

kerneis commented Jan 3, 2022

And if you want to list from all dura branches, and not only the one deriving from HEAD, it's even easier:

git config --global alias.dura '!restore () { local when="$1"; shift; cd "$GIT_PREFIX"; git checkout $(git rev-list -n 1 --branches=dura-* --until "$when") -- ${@:-:/} ; }; restore'

@tkellogg
Copy link
Owner Author

tkellogg commented Jan 4, 2022

Can you send a pull request to add this to the README?

If you're feeling brave, you could even add this to dura serve, somewhere around here so that it gets set every time dura starts up. Libgit2 docs are here, but I think it would look roughly like this:

fn set_git_alias() -> Result<(), Error> {
    let git_alias = "...";
    let cfg = Config::open(Config::find_global()?)?;
    cfg.set_str("alias.dura-reset", git_alias)?;
    Ok(())
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants