Skip to content

Instantly share code, notes, and snippets.

@aldy505
Last active November 9, 2024 00:47
Show Gist options
  • Save aldy505/0556db0d4ea531e36f92f9266baa58e3 to your computer and use it in GitHub Desktop.
Save aldy505/0556db0d4ea531e36f92f9266baa58e3 to your computer and use it in GitHub Desktop.
Bulk git repository updater
################################################################################
# Repo Update
#
# This script updates all the repositories in the current directory and its
# subdirectories. It checks if the current branch is merged to the remote
# branch, and if so, switches to the remote branch. If there are uncommitted
# changes, it skips switching the branch.
#
# Usage:
# repo-update.jl [directory]
#
# If no directory is provided, the script will update all the repositories in
# the current directory.
#
# Author: Reinaldy Rafli <[email protected]>
# License: MIT
################################################################################
# MIT License
#
# Copyright (c) 2024 Reinaldy Rafli <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
argument = pwd()
if length(ARGS) > 0
argument = abspath(argument)
end
for dir in readdir(argument, join=true, sort=true)
if !isdir(dir)
continue
end
subdir = readdir(dir, join=true, sort=true)
# if subdir contains .git, then it's the right repo
if any(x -> endswith(x, ".git"), subdir)
println("Updating $dir")
cd(dir)
run(`git fetch`)
# if the current state is dirty, don't bother executing any other commands
git_dirty_output = IOBuffer()
run(pipeline(`git status --porcelain`, git_dirty_output))
if isempty(String(take!(git_dirty_output)))
# if the current branch name is not `master` or `main`, check if the current branch is merged
merged_output = IOBuffer()
run(pipeline(`git branch -r --merged`, merged_output))
current_branch_output = IOBuffer()
run(pipeline(`git rev-parse --abbrev-ref HEAD`, current_branch_output))
head_name_output = IOBuffer()
run(pipeline(`git rev-parse --abbrev-ref origin/HEAD`, head_name_output))
merged_lists = split(String(take!(merged_output)), "\n")
current_branch = strip(String(take!(current_branch_output)))
head_name = replace(strip(String(take!(head_name_output))), "origin/" => "")
if current_branch != head_name && any(x -> occursin(current_branch, x), merged_lists)
println("$current_branch has been merged to $head_name, switching to $head_name")
run(`git switch $head_name`)
run(`git pull`)
end
else
println("There are uncommitted changes, skipping switching branch")
end
# if has `gitea` remote, then try to push it to the `gitea` upstream
origin_output = IOBuffer()
run(pipeline(`git remote -v`, origin_output))
origin_lists = split(String(take!(origin_output)), "\n")
if any(x -> occursin("gitea", x), origin_lists)
println("Updating to gitea")
run(`git push --all gitea`)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment