GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Support additional worktrees · Issue #719 · gitpython-developers/GitPython

Support additional worktrees #719

New issue
Copy link
New issue
Copy link
Closed as not planned
Feature
Closed as not planned
Support additional worktrees#719
Feature
Copy link
Labels
acknowledgedhelp wanted

Description

@hilkoc
hilkoc
opened on Jan 29, 2018
Issue body actions

As described in this issue: #344 .
Since it's now almost 3 years later, it would be great if support for additional worktrees can be added.

Activity

  1. KellyDeveloped commented on Jan 30, 2018

    @KellyDeveloped
    KellyDeveloped
    on Jan 30, 2018
    More actions

    There isn't a wrapper for worktrees yet, but I found using Repo.git.worktree("add", folder, branch) will load the worktree for you.

    From there you can navigate into the worktree and use it like you world any other worktree.

    To unload the worktree, simply remove the folder and then call Repo.git.worktree("prune").

    This works with the latest version.

    Full example:

    import os
    import git
    import shutil
    
    os.mkdir(<desired-folder>)
    
    repo = git.Repo()
    print (repo) # You'll see the original branch path that you're on here
    
    repo.git.worktree("add", <folder>, <branch>)
    
    test_repo = git.Repo(<folder>)
    print (test_repo) # Now you'll see that with this new git.Repo object that it's referencing your worktree
    print (repo) # Just to confirm that this is pointing to the original location
    
    # Run a simple command to make sure everythings working - might be better to use the wrapper library to confirm though
    print (repo.git.status())
    print (test_repo.git.status())
    
    # Remove the worktree like this:
    shutil.rmtree(<folder>)
    repo.git.worktree("prune")
    
    Reacted by Yasin Balcancı and Jesús Leganés-Combarro
  2. hilkoc commented on Feb 1, 2018

    @hilkoc
    hilkoc
    on Feb 1, 2018
    Author
    More actions

    Thanks for this.
    I managed to get it working. The main problem was this:
    When you're in an additional worktree,

    remote = repo.remote(name='origin')
    remote.push()
    

    does not work.

    So instead, all the remote commands need to be called with repo.git.push() or repo.git.pull() etc.

  3. skharat8 commented on Sep 22, 2018

    @skharat8
    skharat8
    on Sep 22, 2018
    More actions

    @KellyDeveloped @hilkoc

    I am curious how you got this working. The example where you used Repo.git.worktree("add", folder, branch) and then initialized with git.Repo() doesn't seem to work. git.Repo() always throws an InvalidGitRepositoryError when the folder path is a worktree.

    My main objective is to get all the file names from the previous commit, which I can do using "repo.git.diff('HEAD~1', name_only=True)". This works with git clones, but with worktrees, git.Repo() throws an InvalidGitRepositoryError.

    Do you know how I could get this working? or is there another way to get file names from git commits?

  4. KellyDeveloped commented on Sep 22, 2018

    @KellyDeveloped
    KellyDeveloped
    on Sep 22, 2018
    More actions

    @KellyDeveloped @hilkoc

    I am curious how you got this working. The example where you used Repo.git.worktree("add", folder, branch) and then initialized with git.Repo() doesn't seem to work. git.Repo() always throws an InvalidGitRepositoryError when the folder path is a worktree.

    My main objective is to get all the file names from the previous commit, which I can do using "repo.git.diff('HEAD~1', name_only=True)". This works with git clones, but with worktrees, git.Repo() throws an InvalidGitRepositoryError.

    Do you know how I could get this working? or is there another way to get file names from git commits?

    It sounds like you're navigating into the wrong folder. This error throws when you aren't inside any type of git repo. I'd suggest using REPL to go through it line by line and see what folder you're in and checking to see if there's a .git folder in there.

    The .git folder simply points back to the real git repo.

  5. skharat8 commented on Sep 22, 2018

    @skharat8
    skharat8
    on Sep 22, 2018
    More actions

    @KellyDeveloped

    I think the problem is that there is no .git folder for worktrees. There is a .git file instead.

    I tried printing out the path that is_git_dir() is checking in fun.py in GitPython (called in Repo class __init__ function). It looks like it goes in a loop like this and then fails with InvalidGitRepositoryError:

    C:/test_worktree
    C:/test_worktree/.git
    C:/test_clone/.git/worktrees/test_worktree
    C:/test_worktree/.git
    C:/test_clone/.git/worktrees/test_worktree

    Just tried changing the is_git_dir() function to add a check for a file as well, and that actually worked! Since worktrees are not really supported, I am not sure if this would cause other issues, but it seems to initialize the git repo properly with git.Repo() for my use case.

    def is_git_dir(d):
        """ This is taken from the git setup.c:is_git_directory
        function.
        @throws WorkTreeRepositoryUnsupported if it sees a worktree directory. It's quite hacky to do that here,
                but at least clearly indicates that we don't support it.
                There is the unlikely danger to throw if we see directories which just look like a worktree dir,
                but are none."""
        if osp.isdir(d):
            if osp.isdir(osp.join(d, 'objects')) and osp.isdir(osp.join(d, 'refs')):
                headref = osp.join(d, 'HEAD')
                return osp.isfile(headref) or \
                    (osp.islink(headref) and
                     os.readlink(headref).startswith('refs'))
            elif (osp.isfile(osp.join(d, 'gitdir')) and
                  osp.isfile(osp.join(d, 'commondir')) and
                  osp.isfile(osp.join(d, 'gitfile'))):
                raise WorkTreeRepositoryUnsupported(d)
       # Added this for worktree support
        elif osp.isfile(d):
            return True
        return False
    Reacted by Sebastian Thiel
  6. Byron
    added
    acknowledged
    on Oct 14, 2018
  7. Byron commented on Oct 14, 2018

    @Byron
    Byron
    on Oct 14, 2018
    Member
    More actions

    Thanks for sharing all your insights! It's much appreciated and certainly helpful to others.

  8. yarikoptic commented on May 3, 2019

    @yarikoptic
    yarikoptic
    on May 3, 2019
    Contributor
    More actions

    Keeps biting us in DataLad, so if some brave soul gets to resolve it -- would be much appreciated!

  9. Byron
    added
    help wanted
    on Jul 21, 2019
  10. Byron commented on Aug 14, 2019

    @Byron
    Byron
    on Aug 14, 2019
    Member
    More actions

    This was closed via #894 and released with v3.0.0

  11. Byron
    closed this as completedon Aug 14, 2019
  12. ghost added a commit that references this issue on Aug 14, 2019

    Fix performance regression, see #906

    d5cc590
  13. Byron commented on Aug 14, 2019

    @Byron
    Byron
    on Aug 14, 2019
    Member
    More actions

    Reopened as the fix was reverted to deal with the performance regression reported in #906 . We hope to let the fix return in a version that caches the output it receives from git-revparse or obtains the information in another way.

  14. Byron
    reopened this on Aug 14, 2019
  15. Byron
    added the
    Feature
    issue type on Jul 20, 2026
  16. Byron
    closed this as not plannedon Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    acknowledgedhelp wanted

    Type

    Feature

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.