Skip to content

feat: Add support for git worktrees#524

Closed
kamilwaz wants to merge 1 commit intoaltsem:masterfrom
kamilwaz:worktree
Closed

feat: Add support for git worktrees#524
kamilwaz wants to merge 1 commit intoaltsem:masterfrom
kamilwaz:worktree

Conversation

@kamilwaz
Copy link
Copy Markdown
Contributor

@kamilwaz kamilwaz commented Apr 13, 2026

I experimented a bit with worktrees and bare repositories and found a bug where Gitu isn’t able to fetch the history for a worktree created in a bare repository. This PR fixes the issue and makes the tests use the same function to open repositories as regular Gitu.

Update: The issue is actually in libgit2; shallow grafts are not set correctly for "shallow" worktrees.

Error:

-old snapshot
+new results
────────────┬────────────────────────────────────────────────────────────────────────────────────────────────
    1     1 │ ▌On branch main                                                                 |
    2     2 │ ▌Your branch is up to date with 'origin/main'.                                  |
    3     3 │                                                                                 |
    4     4 │  Recent commits                                                                 |
    5       │- Couldn't read log: object not found - no match for id (b66a0bf82020d6a386e94d0…|
          5 │+ 46c81ca main new-branch origin/main add new-file                               |
    6     6 │                                                                                 |
    7     7 │                                                                                 |
    8     8 │                                                                                 |
    9     9 │                                                                                 |
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
   17    17 │                                                                                 |
   18    18 │                                                                                 |
   19    19 │                                                                                 |
   20    20 │                                                                                 |
   21       │-styles_hash: 2b21a6aa63fe13b3
         21 │+styles_hash: 4d5a9a1a08dc1d60
────────────┴────────────────────────────────────────────────────────────────────────────────────────────────

Checklist

  • The modified code has some test-coverage (where applicable).
  • make test is passing (this is what CI runs).
  • New unreleased features/fixes/styling and performance improvements are documented via git: feat: / fix: / style: / perf:. Or e.g. perf(highlighting):.
    See https://github.com/altsem/gitu/blob/master/docs/dev-tooling.md

Comment thread src/lib.rs
fn open_repo(dir: &Path) -> Res<Repository> {
log::debug!("Opening repo");
let repo = open_repo_from_env()?;
let mut repo = Repository::open(dir).map_err(Error::OpenRepo)?;
Copy link
Copy Markdown
Contributor Author

@kamilwaz kamilwaz Apr 13, 2026

Choose a reason for hiding this comment

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

I replaced open_from_env, as GIT_DIR should already be handled by git rev-parse --show-toplevel.

@kamilwaz kamilwaz marked this pull request as draft April 14, 2026 06:16
@kamilwaz
Copy link
Copy Markdown
Contributor Author

kamilwaz commented Apr 14, 2026

I spent some more time on it and it turns out that this is a bug in libgit2. Also, my fix doesn’t actually solve it.

In short, the issue is that libgit2 doesn’t correctly handle shallow grafts for worktrees created in a shallow repository. Shallow grafts should be assigned here:

https://github.com/libgit2/libgit2/blob/1f34e2a57a3d03f174771203b64aed2b17e8522c/src/libgit2/commit.c?plain=1#L563

However, because libgit2 thinks the repository isn't shallow, it doesn’t set them here:

https://github.com/libgit2/libgit2/blob/1f34e2a57a3d03f174771203b64aed2b17e8522c/src/libgit2/repository.c?plain=1#L926-L928

This causes the parent of the latest commit to be returned (as an OID), even though it doesn't exist locally.

I’m closing the PR and will try to address this in libgit2 when I get a chance.

@kamilwaz kamilwaz closed this Apr 14, 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.

1 participant