Skip to content

Commit 3e1b65c

Browse files
Add fetch subcommand
Signed-off-by: Jacob Stopak <jacob@initialcommit.io>
1 parent 0756826 commit 3e1b65c

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Example: `$ git-sim merge <branch>`
2626

2727
## Features
2828
- Run a one-liner git-sim command in the terminal to generate a custom Git command visualization (.jpg) from your repo
29-
- Supported commands: `log`, `status`, `add`, `restore`, `commit`, `stash`, `branch`, `tag`, `reset`, `revert`, `merge`, `rebase`, `cherry-pick`, `switch`, `checkout`
29+
- Supported commands: `log`, `status`, `add`, `restore`, `commit`, `stash`, `branch`, `tag`, `reset`, `revert`, `merge`, `rebase`, `cherry-pick`, `switch`, `checkout`, `fetch`
3030
- Generate an animated video (.mp4) instead of a static image using the `--animate` flag (note: significant performance slowdown, it is recommended to use `--low-quality` to speed up testing and remove when ready to generate presentation-quality video)
3131
- Color commits by parameter, such as author the `--color-by=author` option
3232
- Choose between dark mode (default) and light mode
@@ -126,7 +126,7 @@ $ git-sim <subcommand> -h
126126
* [Manim (Community version)](https://www.manim.community/)
127127

128128
## Commands
129-
Basic usage is similar to Git itself - `git-sim` takes a familiar set of subcommands including "log", "status", "add", "restore", "commit", "stash", "branch", "tag", "reset", "revert", "merge", "rebase", "cherry-pick", "switch", "checkout", along with corresponding options.
129+
Basic usage is similar to Git itself - `git-sim` takes a familiar set of subcommands including "log", "status", "add", "restore", "commit", "stash", "branch", "tag", "reset", "revert", "merge", "rebase", "cherry-pick", "switch", "checkout", "fetch", along with corresponding options.
130130

131131
```console
132132
$ git-sim [global options] <subcommand> [subcommand options]
@@ -292,6 +292,11 @@ Usage: `git-sim checkout [-b] <branch>`
292292
- Checks out `<branch>` into the working directory, i.e. moves `HEAD` to the specified `<branch>`
293293
- The `-b` flag creates a new branch with the specified name `<branch>` and checks it out, assuming it doesn't already exist
294294

295+
### git fetch
296+
Usage: `git-sim fetch <remote> <branch>`
297+
298+
- Fetches the specified `<branch>` from the specified `<remote>` to the local repo
299+
295300
## Video animation examples
296301
```console
297302
$ git-sim --animate reset HEAD^

git_sim/__main__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import git_sim.tag
2222
import git_sim.switch
2323
import git_sim.checkout
24+
import git_sim.fetch
25+
2426
from git_sim.settings import ImgFormat, VideoFormat, settings
2527
from manim import config, WHITE
2628

@@ -206,6 +208,7 @@ def main(
206208
app.command()(git_sim.tag.tag)
207209
app.command()(git_sim.switch.switch)
208210
app.command()(git_sim.checkout.checkout)
211+
app.command()(git_sim.fetch.fetch)
209212

210213

211214
if __name__ == "__main__":

git_sim/fetch.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import sys
2+
import os
3+
from argparse import Namespace
4+
5+
import git
6+
import manim as m
7+
import numpy
8+
import typer
9+
import tempfile
10+
import shutil
11+
import stat
12+
13+
from git_sim.animations import handle_animations
14+
from git_sim.git_sim_base_command import GitSimBaseCommand
15+
from git_sim.settings import settings
16+
17+
18+
class Fetch(GitSimBaseCommand):
19+
def __init__(self, remote: str, branch: str):
20+
super().__init__()
21+
self.remote = remote
22+
self.branch = branch
23+
settings.max_branches_per_commit = 2
24+
25+
if self.remote not in self.repo.remotes:
26+
print("git-sim error: no remote with name '" + self.remote + "'")
27+
sys.exit(1)
28+
29+
def construct(self):
30+
if not settings.stdout and not settings.output_only_path and not settings.quiet:
31+
print(
32+
f"{settings.INFO_STRING } {type(self).__name__.lower()} {self.remote} {self.branch}"
33+
)
34+
35+
self.show_intro()
36+
37+
git_root = self.repo.git.rev_parse("--show-toplevel")
38+
repo_name = os.path.basename(self.repo.working_dir)
39+
new_dir = os.path.join(tempfile.gettempdir(), "git_sim", repo_name)
40+
41+
orig_remotes = self.repo.remotes
42+
self.repo = git.Repo.clone_from(git_root, new_dir, no_hardlinks=True)
43+
for r1 in orig_remotes:
44+
for r2 in self.repo.remotes:
45+
if r1.name == r2.name:
46+
r2.set_url(r1.url)
47+
self.repo.git.fetch(self.remote, self.branch)
48+
49+
# local branch doesn't exist
50+
if self.branch not in self.repo.heads:
51+
start_parse_from_remote = True
52+
# fetched branch is ahead of local branch
53+
elif (self.remote + "/" + self.branch) in self.repo.git.branch(
54+
"-r", "--contains", self.branch
55+
):
56+
start_parse_from_remote = True
57+
# fetched branch is behind local branch
58+
elif self.branch in self.repo.git.branch(
59+
"--contains", (self.remote + "/" + self.branch)
60+
):
61+
start_parse_from_remote = False
62+
else:
63+
start_parse_from_remote = True
64+
65+
if start_parse_from_remote:
66+
commit = self.get_commit(self.remote + "/" + self.branch)
67+
else:
68+
commit = self.get_commit(self.branch)
69+
self.parse_commits(commit)
70+
71+
self.recenter_frame()
72+
self.scale_frame()
73+
self.color_by()
74+
self.fadeout()
75+
self.show_outro()
76+
self.repo.git.clear_cache()
77+
shutil.rmtree(new_dir, onerror=del_rw)
78+
79+
def del_rw(action, name, exc):
80+
os.chmod(name, stat.S_IWRITE)
81+
os.remove(name)
82+
83+
def fetch(
84+
remote: str = typer.Argument(
85+
...,
86+
help="The name of the remote to fetch from",
87+
),
88+
branch: str = typer.Argument(
89+
...,
90+
help="The name of the branch to fetch",
91+
),
92+
):
93+
scene = Fetch(remote=remote, branch=branch)
94+
handle_animations(scene=scene)

0 commit comments

Comments
 (0)