Motivation
Altium has their Altium365 cloud service, which includes Git version control. I wanted to mirror my Altium project to GitHub to add to my portfolio, since my GitHub currently has a lot of programming but not so much embedded projects to show.
Adding a new remote is the most obvious solution.
1
2
git remote add gh https://github.com/OWNER/REPOSITORY.git # gh remote is for github
git push gh master
There are several issues:
- Altium does not work with
ssh
connections, only HTTPS. This is not a problem if you use HTTPS on GitHub. - I had issues with Altium recognizing the
gh
remote as the primary remote, instead of the Altium 365 remote. Obviously, Altium doesn’t seem designed to deal with multiple remotes. - The largest issue is that Altium sets up the
user.email
with the format$NAME@$DOMAIN@$MACHINE_NAME
. This email format is not accepted on GitHub, so the commits do not get attributed to your GitHub account, and they appear in a ‘raw’ form as:$EMAIL
authored and$EMAIL
comitted on$DATE
.
So I bodged together a script to resolve these issues which is probably against all good Git practice, but whatever (I’m not planning to have users contribute to the GitHub side - it will only be a read-only remote).
1
2
3
4
git filter-branch --env-filter '
export GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL%@*}
export GIT_COMMITTER_EMAIL=${GIT_COMMITTER_EMAIL%@*}
' --tag-name-filter cat -- --branches --tags
This command will re-write history to remove everything after the second @
symbol, including the machine name. As we are re-writing history, copy the repository to a new directory. Do not modify the original, since rewriting history is risky and Altium probably relies on the format including the machine name.
Anyway I ChatGPT’d the rest, but it
- Copy all directories in a csv (
$directory_name,$remote_url
) to aZZZ_GITHUB
directory. Projects which are already in the github directory are compared by revision, and if the github copy is out of date then it is copied over. - Reset
--hard
, since the script will be run rarely and a project might be modified but not committed. - Rewrite history, remove machine name from author and committer emails.
- Add new remote and push.
Here’s the script, enjoy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash
# Step 1: Create the "ZZZ_GITHUB" folder if it doesn't exist
mkdir -p ZZZ_GITHUB
# Step 2: Read the list of repository names from "repositories_list.txt" and copy only the listed repositories
while IFS=',' read -r directory remote_url || [ -n "$directory" ]; do
echo "Processing repository: $directory"
source_dir="$directory"
target_dir="ZZZ_GITHUB/$directory"
# Check if the source directory is a valid Git repository
if [ -d "$source_dir/.git" ] && git -C "$source_dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
# Check if the target directory is not present or is out of date
if [ ! -d "$target_dir" ] || ! git -C "$source_dir" diff-index --quiet HEAD -- "$source_dir"; then
# Copy the repository to ZZZ_GITHUB
echo "Copy: $directory . . ."
rm -rf "$target_dir"
cp -r "$source_dir" "$target_dir"
echo "Repository copied: $directory"
git -C "$target_dir" reset --hard HEAD
git -C "$target_dir" filter-branch --env-filter '
export GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL%@*}
export GIT_COMMITTER_EMAIL=${GIT_COMMITTER_EMAIL%@*}
' --tag-name-filter cat -- --branches --tags
git -C "$target_dir" remote set-url origin "$remote_url"
git -C "$target_dir" push --force origin HEAD
echo "Copied repository pushed to the remote: $directory"
else
echo "Repository is up to date: $directory"
fi
else
echo "Invalid Git repository or directory not found: $directory"
fi
done < repositories_list.txt
You can see this script working for the STM32WLE5 development board.