Skip to content

Support customizing clone path pattern#32

Closed
bezbac wants to merge 3 commits intowezm:mainfrom
bezbac:main
Closed

Support customizing clone path pattern#32
bezbac wants to merge 3 commits intowezm:mainfrom
bezbac:main

Conversation

@bezbac
Copy link
Copy Markdown

@bezbac bezbac commented Feb 1, 2026

This PR introduces a --pattern argument (and GRAB_PATTERN env var) as an alternative to the --home argument and GRAB_HOME env variable, allowing users to customize destination paths move heavily using variables extracted from the git url.

I did my best to match the style of the existing code and ensure there are no clippy issues. Please let me know if there's anything I should change :)

Copy link
Copy Markdown
Owner

@wezm wezm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. I think the concept is good overall. Do you have a motivating example this allows that the current behaviour did not?

To merge this, the out-of-the-box behaviour would need to match how git-grab works now. That way if someone upgrades, their setup continues to work. The new default configuration doesn't currently do that. For example, currently git grab --dry-run https://forge.wezm.net/wezm/cports-updates would clone to ~/src/forge.wezm.net/wezm/cports-updates. However, with these changes it clones to ~/src/forge.wezm.net/wezm, which is not what I'd expect.

Comment thread README.md Outdated
Comment on lines +122 to +124
--home (deprecated) [default: $GRAB_HOME]
The ~ character or {home} placeholder in the pattern expands to this
directory.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description doesn't match the behaviour of --home in the current version, which I think should be preserved.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --pattern argument now supersedes the ⁠--home argument. If a user configures a pattern that does not start with a⁠ ~ character or use the ⁠{home} placeholder, ⁠--home will have no effect.

Here's the current description

The directory to use as "grab home", where the URLs will cloned into. Overrides the GRAB_HOME environment variable if set.

I believe the original description might be confusing in this context, so I feel the updated version is more accurate.

Comment thread src/args.rs Outdated
#[cfg(not(feature = "clipboard"))]
const SUPPORTS_CLIPBOARD: bool = false;

pub struct GrabPattern(pub String);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally the pattern would be parsed into the components here, so that we know a GrabPattern instance is valid if constructed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in ce41c2f

Comment thread src/grab.rs
Comment on lines +304 to +312
"/src/{host/}{owner/}{repo}",
"git://c9x.me/qbe.git",
"/src/c9x.me/qbe",
),
(
"/src/{host}/{owner}/{repo}",
"git://c9x.me/qbe.git",
"/src/c9x.me//qbe",
),
Copy link
Copy Markdown
Owner

@wezm wezm Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the version without the / in the placeholders is the same, is there any reason to support slashes in the placeholders?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They do behave differently. It's a little hard to see but visible in the test cases. In the examples, /src/{host/}{owner/}{repo} would evaluate to /src/c9x.me/qbe, whereas /src/{host}/{owner}/{repo} evaluates to /src/c9x.me//qbe. Note the double // character in the second example. Since some variables/placeholders may not be extractable based on the URL, I think this makes sense.

An alternative would be to automatically remove double slashes. This leads to less verbose configuration but feels a little more "magic" to me. I'm not sure if there is ever a case where a user would want the slash to be preserved.

Comment thread src/grab.rs
let url_components = extract_url_components(url);
let home_string = home.as_ref().map(|p| p.to_string_lossy().to_string());

while !remaining.is_empty() {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some extra validation required here. --pattern currently seems to accept empty strings or strings with only whitespace.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in ce41c2f

@bezbac
Copy link
Copy Markdown
Author

bezbac commented Feb 3, 2026

Thank you for taking the time to review this and respond so quickly.

The motivation behind this was that for my own use, I do not care much about the host domain of the git repositories, since I almost exclusively interact with GitHub as a forge.

Personally, I wanted target paths like ~/dev/repos/bezbac/dotfiles. Since, in the current version, there is no way to exclude the domain such as forge.wezm.net by default, I thought this --pattern argument would be the most flexible long-term. I have already configured this to my liking and have been using it; the relevant configuration is publicly available in my dotfiles: bezbac/dotfiles@e3aa152.

Regarding backwards compatibility, you are absolutely correct. I intended it to be backwards compatible but must have messed up somewhere. I will update the PR so that the code is, in fact, backwards compatible.

@bezbac
Copy link
Copy Markdown
Author

bezbac commented Feb 5, 2026

I've updated the pull request so that the default behavior now aligns with the existing version. I also added some more test cases that hopefully convey this backwards compatibility.

Two of your comments remain only partially addressed; please let me know if you disagree with my approach on these.

@bezbac bezbac requested a review from wezm February 5, 2026 18:26
@wezm
Copy link
Copy Markdown
Owner

wezm commented Apr 27, 2026

I've given this some more thought and additional review and I don't think I'm going to merge this change. The pattern feature adds complexity and edge cases that I'm not sure are worth the flexibility it allows. The current version of git-grab is simple and ambivalent to the particular host by dutifully replicating the hierarchy of the URL. This PR adds the need to know about particular git hosts, which doesn't work when people and projects are able to have the own instances of GitLab, Forgejo, etc. Such as https://gitlab.alpinelinux.org/alpine and https://forge.fedoraproject.org/. I'm sorry for wasting the time you put into this PR.

For the specific use case you have of wanting to not organise by host I think this is simple and self contained enough to implement on its own. There could be a --skip-host flag and GRAB_SKIP_HOST env var to control the behaviour, and if set we'd skip this line, and that would be the whole change (as far as I can see).

path.push(url.host_str().ok_or("invalid hostname")?);

@bezbac
Copy link
Copy Markdown
Author

bezbac commented Apr 27, 2026

Hi wezm, no worries at all. I completely understand not wanting to increase complexity. None of my time was wasted. I’ve been using my fork for the past few months and am happy to continue doing so even if this isn’t merged. Thanks for letting me know 🙏

@bezbac bezbac closed this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants