Skip to content

Commit

Permalink
Add recursive git scripts. (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
calvertdw authored Nov 13, 2024
1 parent d7ae876 commit 3d30f37
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 9 deletions.
42 changes: 42 additions & 0 deletions .tools/common_git_functions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Function to check if a directory is a Git repository
is_git_repo() {
git -C "$1" rev-parse --is-inside-work-tree &>/dev/null
}

find_repo_dirs() {
# 1. Recursively find .git folders.
# 2. Remove the /.git from path.
# 3. Make the path relative.
# 4. Sort paths alphabetically.
find "$(pwd)" -type d -name ".git" -print0 \
| xargs -0 -I {} dirname {} \
| xargs -I {} realpath --relative-to="$(pwd)" {} \
| sort
}

# Recursively runs git commands on all git repos in a directory
git_recursive() {
mapfile -t repo_dirs < <(find_repo_dirs)

for repo_dir in "${repo_dirs[@]}"; do
if is_git_repo "$repo_dir"; then
echo "git -C \"$repo_dir\" $*"
git -C "$repo_dir" "$@"
fi
done
}

# Deletes branches that used to have a matching ref on the remote, but it has
# been deleted. This happens when PRs are merged.
# (Not sure how to share the common code with the above)
git_recursive_delete_merged_branches() {
mapfile -t repo_dirs < <(find_repo_dirs)

for repo_dir in "${repo_dirs[@]}"; do
if is_git_repo "$repo_dir"; then
echo "git -C \"$repo_dir\" for-each-ref --format '%(refname:short) %(upstream:track)' | awk '\$2 == "[gone]" {print \$1}' | xargs -r git -C \"$repo_dir\" branch -D"
git -C "$repo_dir" for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == "[gone]" {print $1}' | xargs -r git -C "$repo_dir" branch -D
fi
done
}

4 changes: 4 additions & 0 deletions .tools/git_recursive.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

source "$(dirname "$0")/common_git_functions.sh"
git_recursive "$@"
4 changes: 4 additions & 0 deletions .tools/git_recursive_delete_merged_branches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

source "$(dirname "$0")/common_git_functions.sh"
git_recursive_delete_merged_branches
17 changes: 17 additions & 0 deletions .tools/git_recursive_reset_branch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

source "$(dirname "$0")/common_git_functions.sh"

git_recursive fetch --all --prune
git_recursive checkout develop
git_recursive reset --hard
git_recursive pull

git_recursive_delete_merged_branches

if [ "$1" != "develop" ]; then
git_recursive checkout "$1"
git_recursive reset --hard
git_recursive pull
git_recursive rebase develop
fi
41 changes: 32 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,39 @@ These files are compatible with projects that use the [ihmc-build](https://githu

### Starting from scratch

Use [repository-collections](https://github.com/ihmcrobotics/repository-collections) or build the repo structure manually:

- `git clone` this repository.
- `cd repository-group`
- `git clone` project repositories into it.

Normally, nesting Git repos inside of each other is frowned upon, but in this case, the .gitignore uses a whitelist instead of a blacklist, so your repos won't be affected by Git operations on repository-group.
Normally, nesting Git repos inside each other is frowned upon, but in this case, the .gitignore uses a whitelist instead of a blacklist, so your repos won't be affected by Git operations on repository-group.

### Maintaining the workspace

We provide recursive git scripts in the `.tools` directory to help keep your group up to date.

```
# Perform Git operation on all repos including this one
repository-group $ .tools/git_recursive.sh [git args ...]
# Delete local branches after the PR has been merged.
repository-group $ .tools/git_recursive_delete_merged_branches.sh
# Reset to a branch and rebase it with develop.
# WARNING: Discard local changes first!
# This checks out develop, pulls, fetches,
# checks out, and rebases your branch onto develop.
repository-group $ .tools/git_recursive_reset_branch.sh branch-name
# Examples:
# Fetch all repos
repository-group $ .tools/git_recursive.sh fetch --all
# Start working on your feature and make sure you're up to date with develop
repository-group $ .tools/git_recursive_reset_branch.sh feature/improvements
```

### Convert your existing folder to a repository-group

Expand All @@ -28,10 +56,6 @@ git reset origin/develop --hard
git branch --set-upstream-to origin/develop develop
```

### Staying up to date

`git pull` to update to the latest ihmc-build plugin.

### Cleaning up build files

Run `gradle cleanBuild --console=plain` to clean all `build/` (Gradle), `bin/` (Eclipse IDE), and `out/` (IntelliJ IDE) build directories.
Expand All @@ -40,11 +64,11 @@ This sometimes helps to forces IDEs to recompile the code when state becomes inc

### Gradle install scripts

This repo contains helper scripts (in the `tools` directory) to install Gradle system-wide. There are installation scripts for both Linux (Ubuntu) and Windows.
This repo contains helper scripts (in the `.tools` directory) to install Gradle system-wide. There are installation scripts for both Linux (Ubuntu) and Windows.

**Linux usage:**
```
cd repository-group/tools
cd repository-group/.tools
sudo bash installGradle-<version>.sh
```
**Windows usage:**<br>
Expand All @@ -55,5 +79,4 @@ Open a file explorer to the repository-group/tools directory. Right click on `in
Support is provided through Github issues.

Duncan Calvert (dcalvert@ihmc.org)

**This repo is read-only. Do not attempt to push your changes!**
Dexton Anderson (danderson@ihmc.org)

0 comments on commit 3d30f37

Please sign in to comment.