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

Freeze and clone worktrees #152

Closed
jackjackk opened this issue May 26, 2021 · 7 comments · Fixed by #167
Closed

Freeze and clone worktrees #152

jackjackk opened this issue May 26, 2021 · 7 comments · Fixed by #167
Labels
good first issue Good for newcomers

Comments

@jackjackk
Copy link

I've just discovered gita and it seems great, thanks a lot!
One feature that I would find useful is the following. I have a relatively large git repo of which I might need to test and maintain several branches at the same time. Instead of checking out each branch each time, I'm using worktrees: from the master/main clone, if BRANCH=my-branch-name, I use:

git worktree add --checkout ../$(basename $(pwd))-${BRANCH} ${BRANCH}

to create at the parent level a sibling folder with a reasonable name and with the checked out branch inside but without replicating all the .git info.
Since I'm interested in replicating and keeping in sync my multi-repo git setup across two computers, and hence in possibly using the gita freeze/clone for this, I was wondering whether the worktree approach could be included in the freeze/clone mechanics, possibly by leveraging on the output of git worktree list.

Happy to test or take up some coding if you can give me some pointers, if you think all this makes sense!

@nosarthur
Copy link
Owner

I actually never used worktree before...

Do you add the extra worktree folder to gita too, so that you can see both branches in gita ll? Given this is the case, gita freeze shows both repos with the same remote but different names. This would cause cloning twice though

We can to define a new repo type, say w for worktree, which are repos with more than 1 worktrees. Then let the gita freeze only display one of them. How does this sound?

BTW, I am curious how did you discover this gita project?

@jackjackk
Copy link
Author

jackjackk commented May 26, 2021

Just trying to optimize my workflow, you're the 2nd google result of a "manage multiple git repos" search, and then I "validated" the search against Hackernews.

I think your proposal sounds good. Notice that a worktree repo is also recognizibile as its .git is not a directory but a yaml file with a gitdir entry pointing to some worktree file path under the related main repo". So perhaps I would treat as "w" only those with this characteristics (then in the cloning it's a matter of finding the repo w/ the same remote but without a "w" type from which to spin off the worktree) (or extract this info with some porcelain git command which I don't know!).

@nosarthur
Copy link
Owner

nosarthur commented May 26, 2021

Just trying to optimize my workflow, you're the 2nd google result of a "manage multiple git repos" search, and then I "validated" the search against Hackernews.

Interesting.

To make it even simpler, we can just remove url redundancies in gita freeze. It seems to be safe.

@nosarthur
Copy link
Owner

I was about to ask if the 'original' and the 'branched-out' worktrees are on the same footing. It's not clear to me how one can tell which one is 'original' from the git worktree command. Your comment answered it. At the time, I was assuming they were on the same footing

As a result, there are actually 2 type of working tree repos. Maybe we don't need to worry all these details for now.

I am also curious what happens if one branches out a worktree, then git worktree remove the original one. Maybe it's not allowed.

@nosarthur
Copy link
Owner

Notice that a worktree repo is also recognizibile as its .git is not a directory but a yaml file with a gitdir entry pointing to some worktree file path under the related main repo".

This may not be the best approach. The git-submodule repos have this format too. In the following example, the qmk_firmware is the real repo with remote URL. The others are submodule repos without remote

13:34 dzhou (master *) qmk_firmware $ gita ll
chibios         pre-breaking_2020_q1  Read serial USB buffer size from the queue (3 years, 4 months ago)
chibios-contrib pre-breaking_2020q1  Merge branch 'fix_kinesis_usb_data_sync' into qmk (3 years, 4 months ago)
googletest      release-1.8.0  Merge pull request #821 from mazong1123/master (4 years, 10 months ago)
qmk_firmware    master *_  clean up (10 months ago)
ugfx            pre-breaking_2020q1  Merge branch 'fix_duplicate_const' into qmk_2.7 (4 years ago)
13:34 dzhou (master *) qmk_firmware $ g worktree list
/Users/dzhou/src/qmk_firmware  83a051aec [master]
13:34 dzhou (master *) qmk_firmware $ cat lib/ugfx/.git
gitdir: ../../.git/modules/lib/ugfx
13:34 dzhou (master *) qmk_firmware $ cd lib/ugfx
/Users/dzhou/src/qmk_firmware/lib/ugfx
13:34 dzhou ((pre-breaking_2020q1)) ugfx $ g worktree list
/Users/dzhou/src/qmk_firmware/.git/modules/lib/ugfx  3e97b74e (detached HEAD)

@jackjackk
Copy link
Author

Thanks, this is a .git of a worktree:

gitdir: /home/jack/working/witch/.git/worktrees/witch-openwitchrc2b

so maybe matching the string .git/worktrees/ ?

@nosarthur
Copy link
Owner

nosarthur commented May 26, 2021

I think we can simply make a set of the URLs to deduplicate, and forget about detecting working tree repos. The change will be very local in __main__.py

   92 def f_freeze(_):
   93     repos = utils.get_repos()
   94     for name, prop in repos.items():
   95         path = prop['path']
   96         # TODO: What do we do with main repos? Maybe give an option to print
   97         #       their sub-repos too.
   98         url = ''
   99         cp = subprocess.run(['git', 'remote', '-v'], cwd=path, capture_output=True)
  100         lines = cp.stdout.decode('utf-8').split('\n')
  101         if cp.returncode == 0 and len(lines) > 0:
  102             parts = lines[0].split()
  103             if len(parts)>1:
  104                 url = parts[1]
  105         print(f'{url},{name},{path}')
  106

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

Successfully merging a pull request may close this issue.

2 participants