Skip to content

Commit ad58f89

Browse files
committed
Bugfix git-idm for newer versions of git
Use only include and includeIf paths for setting all configurations except for user name and email. git-idm 0.9 works on git version 2.25.1. However, tracked directories is broken for git-idm 0.9 using git version 2.38.1. Config migration is transparent to user.
1 parent ee85849 commit ad58f89

File tree

2 files changed

+120
-54
lines changed

2 files changed

+120
-54
lines changed

CHANGELOG.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
# git-idm v0.10
2+
3+
Important Notes:
4+
5+
- Global settings will automatically be removed.
6+
- If using an older version of Git such as git version 2.25.1 on Ubuntu 20.04
7+
then there's no need to upgrade.
8+
9+
Bug fixes:
10+
11+
- Bugfix tracked directories is broken for git version 2.38.1.
12+
113
# git-idm v0.9
214

3-
Importante Notes:
15+
Important Notes:
416

517
- The bugfix for active identity includes a backwards compatible config
618
migration. This config migration code will be removed after 5 or 6 releases
@@ -11,6 +23,11 @@ Bug fixes:
1123
- Show proper active identity within a tracked directory. Before, it would only
1224
show the global identity and didn't properly sanity check the identity.
1325

26+
New features:
27+
28+
- New command `git idm copy-key-to` which copies SSH keys from other identities
29+
into the specified identity. This command is more for migration purposes.
30+
1431
# git-idm v0.8
1532

1633
New features:

git-idm

Lines changed: 102 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#License: MIT
44
#Project URL: https://github.com/samrocketman/git-identity-manager
55

6-
version='0.9'
6+
version='0.10'
77

88
if ! git --version | awk 'BEGIN { FS="." }; $2 < 13 { exit(1) }'; then
99
echo 'WARNING: "git --version" is older than Git 2.13. git-idm will have unexpected behavior.' >&2
@@ -15,9 +15,9 @@ function echo_version() {
1515

1616
function remove_tracked_identities() {
1717
git config --global --list |
18-
grep -i "includeif\.gitdir:.*\.idm=${id}" |
19-
sed "s/\\.idm=${id}\$//" |
20-
sed 's/^includeif/includeIf/' |
18+
grep -i "includeif\.gitdir:.*\.idm=${id}" |
19+
sed "s/\\.idm=${id}\$//" |
20+
sed 's/^includeif/includeIf/' |
2121
while read -r section; do
2222
run_command git config --global --remove-section "${section}"
2323
done
@@ -47,7 +47,7 @@ function list_identities() {
4747
'
4848
}
4949

50-
# TODO: remove migration 5 or 6 releases after v0.9.
50+
# TODO: remove migration 5 releases after v0.9.
5151
function migrate_active_identities() {
5252
local stored_id=""
5353
local migrate=false
@@ -62,6 +62,56 @@ function migrate_active_identities() {
6262
done
6363
}
6464

65+
# TODO: remove migration 5 releases after v0.10.
66+
function migrate_global_config() {
67+
if git config -f ~/.gitconfig --get core.sshCommand > /dev/null; then
68+
run_command git config -f ~/.gitconfig --unset core.sshCommand
69+
fi
70+
if git config -f ~/.gitconfig --get user.signingkey > /dev/null; then
71+
run_command git config -f ~/.gitconfig --unset user.signingkey
72+
fi
73+
if git config -f ~/.gitconfig --get commit.gpgsign; then
74+
run_command git config -f ~/.gitconfig --unset commit.gpgsign
75+
fi
76+
}
77+
78+
function no_ssh_key_warning() {
79+
local SSH_COMMAND="$(git config --global --get gitidm."${1}".sshCommand)"
80+
if [ -z "${SSH_COMMAND:-}" ]; then
81+
echo >&2
82+
echo "WARNING: ${1} identity has no SSH key." >&2
83+
echo ' Copy an SSH key from another identity with copy-key-to command.' >&2
84+
echo ' See "git idm help" for usage.' >&2
85+
fi
86+
}
87+
88+
function add_identity_file() {
89+
if [ -f ~/".gitconfig_idm_${1}" ]; then
90+
return
91+
fi
92+
local NAME="$(git config --global --get gitidm."${1}".name)"
93+
local EMAIL="$(git config --global --get gitidm."${1}".email)"
94+
local SSH_COMMAND="$(git config --global --get gitidm."${1}".sshCommand)"
95+
local SIGNING_KEY="$(git config --global --get gitidm."${1}".signingKey)"
96+
local SIGN_COMMITS="$(git config --global --get gitidm."${1}".signCommits)"
97+
if [ -n "${NAME}" ]; then
98+
run_command git config --file ~/".gitconfig_idm_${1}" user.name "${NAME}"
99+
fi
100+
if [ -n "${EMAIL}" ]; then
101+
run_command git config --file ~/".gitconfig_idm_${1}" user.email "${EMAIL}"
102+
fi
103+
if [ -n "${SSH_COMMAND}" ]; then
104+
run_command git config --file ~/".gitconfig_idm_${1}" core.sshCommand "${SSH_COMMAND}"
105+
fi
106+
if [ -n "${SIGNING_KEY}" ]; then
107+
run_command git config --file ~/".gitconfig_idm_${1}" user.signingkey "${SIGNING_KEY}"
108+
fi
109+
if [ -n "${SIGN_COMMITS}" ]; then
110+
run_command git config --file ~/".gitconfig_idm_${1}" commit.gpgsign "${SIGN_COMMITS}"
111+
fi
112+
run_command git config --file ~/".gitconfig_idm_${1}" user.activeidm "${1}"
113+
}
114+
65115
function usage() {
66116
local cmd="${0##*/git-}"
67117
cat >&2 <<EOF
@@ -94,11 +144,16 @@ Example usage:
94144
95145
git ${cmd} list jcool --tracked
96146
147+
Copy SSH key from another identity.
148+
149+
git ${cmd} copy-key-to jcool --from-id work
150+
97151
Commands:
98152
99153
active - Display the identity currently used by git idm.
100154
add - Add or update an identity. --name, --email, and --key are
101155
required when adding an identity for the first time only.
156+
copy-key-to - Copy an SSH key from another identity.
102157
list - List identities. ls for short. Alternately list track
103158
directories.
104159
remove - Remove a single identity or all identities. rm for short.
@@ -122,6 +177,9 @@ Command options:
122177
--signing-key SIGNING_KEY - (optional) add a gpg signing key.
123178
--sign-commits SIGN_COMMITS (optional) whether or not to sign commits.
124179
--ssh-command SSH_COMMAND - Customize the SSH command ignoring --key.
180+
copy-key-to:
181+
ID - Identity to copy an SSH key to.
182+
--from-id ID - The source identity to copy the SSH key from.
125183
list:
126184
Has no options.
127185
list: (alternate usage)
@@ -166,15 +224,17 @@ function print_identities() {
166224
}
167225

168226
function run_command() {
227+
local args=( "$@" )
169228
case $4 in
170229
user.name|user.email|core.sshCommand)
171-
echo "$1 $2 $3 $4 \"$5\""
230+
msg=( "$1" "$2" "$3" "$4" \""$5"\" )
231+
echo "${msg[@]} $*"
172232
;;
173233
*)
174234
echo "$*"
175235
;;
176236
esac
177-
"$@"
237+
"${args[@]}"
178238
}
179239

180240
function identity_exists() {
@@ -201,6 +261,7 @@ EMAIL=""
201261
SSH_KEY=""
202262
SSH_COMMAND=""
203263
DIRECTORY=""
264+
FROM_ID=""
204265
LIST_TRACKED=false
205266
if [ -z "${comm}" ]; then
206267
echo "ERROR: command not specified. See 'git idm help'."
@@ -269,6 +330,10 @@ while [[ $# -gt 0 ]]; do
269330
LIST_TRACKED=true
270331
shift
271332
;;
333+
--from-id)
334+
FROM_ID="$2"
335+
shift 2
336+
;;
272337
-h)
273338
usage
274339
;;
@@ -338,6 +403,7 @@ EOF
338403
echo "ERROR: found above discrepencies with identity. To fix run 'git idm use ${ACTIVE_ID}'." >&2
339404
exit 1
340405
fi
406+
no_ssh_key_warning "${ACTIVE_ID}"
341407
else
342408
echo 'No identites are active.'
343409
fi
@@ -356,24 +422,37 @@ EOF
356422
exit 1
357423
fi
358424
if [ -n "${NAME}" ]; then
359-
git config --global gitidm."${id}".name "${NAME}"
425+
run_command git config --global gitidm."${id}".name "${NAME}"
360426
fi
361427
if [ -n "${EMAIL}" ]; then
362-
git config --global gitidm."${id}".email "${EMAIL}"
428+
run_command git config --global gitidm."${id}".email "${EMAIL}"
363429
fi
364430
if [ -n "${SSH_KEY}" ]; then
365-
git config --global gitidm."${id}".sshKey "${SSH_KEY}"
431+
run_command git config --global gitidm."${id}".sshKey "${SSH_KEY}"
366432
check_ssh_agent "${SSH_KEY}"
367433
fi
368434
if [ -n "${SSH_COMMAND}" ]; then
369-
git config --global gitidm."${id}".sshCommand "${SSH_COMMAND}"
435+
run_command git config --global gitidm."${id}".sshCommand "${SSH_COMMAND}"
370436
fi
371437
if [ -n "${SIGNING_KEY}" ]; then
372-
git config --global gitidm."${id}".signingKey "${SIGNING_KEY}"
438+
run_command git config --global gitidm."${id}".signingKey "${SIGNING_KEY}"
373439
fi
374440
if [ -n "${SIGN_COMMITS}" ]; then
375-
git config --global gitidm."${id}".signCommits "${SIGN_COMMITS}"
441+
run_command git config --global gitidm."${id}".signCommits "${SIGN_COMMITS}"
376442
fi
443+
add_identity_file "${id}"
444+
no_ssh_key_warning "${id}"
445+
;;
446+
copy-key-to)
447+
SSH_KEY="$(git config --global --get gitidm."${FROM_ID}".sshKey)"
448+
SSH_COMMAND="$(git config --global --get gitidm."${FROM_ID}".sshCommand)"
449+
if [ -z "${SSH_KEY:-}" ] || [ -z "${SSH_COMMAND:-}" ]; then
450+
echo "ERROR: ${FROM_ID} identity has no SSH key." >&2
451+
echo ' See "git idm ls" or "git idm help".' >&2
452+
exit 1
453+
fi
454+
run_command git config --global gitidm."${id}".sshKey "${SSH_KEY}"
455+
check_ssh_agent "${SSH_KEY}"
377456
;;
378457
help)
379458
usage
@@ -411,29 +490,10 @@ EOF
411490
echo 'ERROR: git idm track <identity> --directory <directory> requires --directory option to be passed. See "git idm help".' >&2
412491
exit 1
413492
fi
414-
NAME="$(git config --global --get gitidm."${id}".name)"
415-
EMAIL="$(git config --global --get gitidm."${id}".email)"
416-
SSH_COMMAND="$(git config --global --get gitidm."${id}".sshCommand)"
417-
SIGNING_KEY="$(git config --global --get gitidm."${id}".signingKey)"
418-
SIGN_COMMITS="$(git config --global --get gitidm."${id}".signCommits)"
419-
if [ -n "${NAME}" ]; then
420-
run_command git config --file ~/".gitconfig_idm_${id}" user.name "${NAME}"
421-
fi
422-
if [ -n "${EMAIL}" ]; then
423-
run_command git config --file ~/".gitconfig_idm_${id}" user.email "${EMAIL}"
424-
fi
425-
if [ -n "${SSH_COMMAND}" ]; then
426-
run_command git config --file ~/".gitconfig_idm_${id}" core.sshCommand "${SSH_COMMAND}"
427-
fi
428-
if [ -n "${SIGNING_KEY}" ]; then
429-
run_command git config --file ~/".gitconfig_idm_${id}" user.signingkey "${SIGNING_KEY}"
430-
fi
431-
if [ -n "${SIGN_COMMITS}" ]; then
432-
run_command git config --file ~/".gitconfig_idm_${id}" commit.gpgsign "${SIGN_COMMITS}"
433-
fi
434-
run_command git config --file ~/".gitconfig_idm_${id}" user.activeidm "${id}"
493+
add_identity_file "${id}"
435494
run_command git config --global includeIf."gitdir:${DIRECTORY}".idm "${id}"
436495
run_command git config --global includeIf."gitdir:${DIRECTORY}".path ~/".gitconfig_idm_${id}"
496+
no_ssh_key_warning "${id}"
437497
;;
438498
uninstall)
439499
"$0" remove all
@@ -450,35 +510,24 @@ EOF
450510
fi
451511
NAME="$(git config --global --get gitidm."${id}".name)"
452512
EMAIL="$(git config --global --get gitidm."${id}".email)"
453-
SSH_COMMAND="$(git config --global --get gitidm."${id}".sshCommand)"
454-
SSH_KEY="$(git config --global --get gitidm."${id}".sshKey)"
455-
SIGNING_KEY="$(git config --global --get gitidm."${id}".signingKey)"
456-
SIGN_COMMITS="$(git config --global --get gitidm."${id}".signCommits)"
457513
if [ -n "${NAME}" ]; then
458514
run_command git config --global user.name "${NAME}"
459515
fi
460516
if [ -n "${EMAIL}" ]; then
461517
run_command git config --global user.email "${EMAIL}"
462518
fi
463-
if [ -n "${SSH_COMMAND}" ]; then
464-
run_command git config --global core.sshCommand "${SSH_COMMAND}"
465-
fi
466-
if [ -n "${SIGNING_KEY}" ];
467-
then
468-
run_command git config --global user.signingkey "${SIGNING_KEY}"
469-
else
470-
run_command git config --global --unset user.signingkey
471-
fi
472-
if [ -n "${SIGN_COMMITS}" ];
473-
then
474-
run_command git config --global commit.gpgsign "${SIGN_COMMITS}"
475-
else
476-
run_command git config --global --unset commit.gpgsign
519+
if ! git config --global --get include.path '_idm_' > /dev/null; then
520+
run_command git config --global --add include.path ~/".gitconfig_idm_${id}"
521+
else
522+
run_command git config --global --replace-all include.path ~/".gitconfig_idm_${id}" '_idm_'
477523
fi
524+
migrate_global_config
478525
run_command git config --global user.activeidm "${id}"
479526
if [ -n "${SSH_KEY}" ]; then
480-
check_ssh_agent "${SSH_KEY}"
527+
check_ssh_agent "${SSH_KEY}"
481528
fi
529+
add_identity_file "${id}"
530+
no_ssh_key_warning "${id}"
482531
;;
483532
version)
484533
echo_version

0 commit comments

Comments
 (0)