Tutorial
Here, you'll find a quick overview over the most common functionality of GRM.
Managing existing repositories
Let's say you have your git repositories at ~/code
. To start managing them via
GRM, first create a configuration:
grm repos find local ~/code --format yaml > ~/code/config.yml
The result may look something like this:
---
trees:
- root: ~/code
repos:
- name: git-repo-manager
worktree_setup: true
remotes:
- name: origin
url: "https://github.com/hakoerber/git-repo-manager.git"
type: https
To apply the configuration and check whether all repositories are in sync, run the following:
$ grm repos sync config --config ~/code/config.yml
[✔] git-repo-manager: OK
Well, obiously there are no changes. To check how changes would be applied,
let's change the name of the remote (currently origin
):
$ sed -i 's/name: origin/name: github/' ~/code/config.yml
$ grm repos sync config --config ~/code/config.yml
[⚙] git-repo-manager: Setting up new remote "github" to "https://github.com/hakoerber/git-repo-manager.git"
[⚙] git-repo-manager: Deleting remote "origin"
[✔] git-repo-manager: OK
GRM replaced the origin
remote with github
.
The configuration (~/code/config.yml
in this example) would usually be
something you'd track in git or synchronize between machines via some other
means. Then, on every machine, all your repositories are a single grm repos sync
away!
Getting repositories from a forge
Let's say you have a bunch of repositories on GitHub and you'd like to clone them all to your local machine.
To authenticate, you'll need to get a personal access token, as described in
the forge documentation. Let's assume you put
your token into ~/.github_token
(please don't if you're doing this "for
real"!)
Let's first see what kind of repos we can find:
$ grm repos sync remote --provider github --token-command "cat ~/.github_token" --root ~/code/github.com/ --format yaml
---
trees: []
$
Ummm, ok? No repos? This is because you have to tell GRM what to look for (if you don't, GRM will just relax, as it's lazy).
There are different filters (see the forge
documentation for more info). In our case,
we'll just use the --owner
filter to get all repos that belong to us:
$ grm repos find remote --provider github --token-command "cat ~/.github_token" --root ~/code/github.com/ --format yaml
---
trees:
- root: ~/code/github.com
repos:
- name: git-repo-manager
worktree_setup: false
remotes:
- name: origin
url: "https://github.com/hakoerber/git-repo-manager.git"
type: https
Nice! The format is the same as we got from grm repos find local
above. So if
we wanted, we could save this file and use it with grm repos sync config
as
above. But there is an even easier way: We can directly clone the repositories!
$ grm repos sync remote --provider github --token-command "cat ~/.github_token" --root ~/code/github.com/
[⚙] Cloning into "~/code/github.com/git-repo-manager" from "https://github.com/hakoerber/git-repo-manager.git"
[✔] git-repo-manager: Repository successfully cloned
[✔] git-repo-manager: OK
Nice! Just to make sure, let's run the same command again:
$ grm repos sync remote --provider github --token-command "cat ~/.github_token" --root ~/code/github.com/
[✔] git-repo-manager: OK
GRM saw that the repository is already there and did nothing (remember, it's lazy).
Using worktrees
Worktrees are something that make it easier to work with multiple branches at the same time in a repository. Let's say we wanted to hack on the codebase of GRM:
$ cd ~/code/github.com/git-repo-manager
$ ls
.gitignore
Cargo.toml
...
Well, this is just a normal git repository. But let's try worktrees! First, we
have to convert the existing repository to use the special worktree setup. For
all worktree operations, we will use grm worktree
(or grm wt
for short):
$ grm wt convert
[✔] Conversion done
$ ls
$
So, the code is gone? Not really, there is just no active worktree right now. So
let's add one for master
:
$ grm wt add master --track origin/master
[✔] Conversion done
$ ls
master
$ (cd ./master && git status)
On branch master
nothing to commit, working tree clean
Now, a single worktree is kind of pointless (if we only have one, we could also
just use the normal setup, without worktrees). So let's another one for
develop
:
$ grm wt add develop --track origin/develop
[✔] Conversion done
$ ls
develop
master
$ (cd ./develop && git status)
On branch develop
nothing to commit, working tree clean
What's the point? The cool thing is that we can now start working in the
develop
worktree, without affecting the master
worktree at all. If you're
working on develop
and want to quickly see what a certain file looks like in
master
, just look inside ./master
, it's all there!
This becomes especially interesting when you have many feature branches and are working on multiple features at the same time.
There are a lot of options that influence how worktrees are handled. Maybe you
want to automatically track origin/master
when you add a worktree called
master
? Maybe you want your feature branches to have a prefix, so when you're
working on the feature1
worktree, the remote branch will be
origin/awesomefeatures/feature1
? Check out the chapter on
worktrees for all the things that are possible.