aboutsummaryrefslogtreecommitdiff
path: root/git-config-save
blob: dad19ef0054a9a8475d83451355a12b73bfe43f3 (plain)
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/bin/bash
#
# Save/restore your .git/config files in a central place.
#
# When called as "git-config-save" or "git config-save",
# this scripts traverses a folder looking for all .git/config files
# and makes backups at ~/.config/gitconfigs.
#
# When called as "git-config-restore" or "git config-restore"
# it does the reverse operation: restores all .git/config
# files, replacing the current repository .git/config's by the one
# available from ~/.config/gitconfigs.
#
# Use cases:
#
#   - You work with the repositories in multiple machines and is
#     looking for a way to sync not just the content but also the
#     same repository configuration (user name, remotes, etc).
#
#   - You want to delete working copies of repositories but want
#     to keep each repository configuration for future use. In that
#     case all you have to do is to clone the repository again and
#     run this command inside your working copy.
#
# You may want to put in a schedule job to process all your stuff regularly.
#
# Storage format:
#
#   - Use ~/.config/gitconfigs/ as base.
#   - Repository identifier is determined by it's path in the system.
#     That's the best choice if you have the same repository checked out
#     multiple times and with different configurations.
#   - Repository identifier can also be determined by the first commit ID
#     (not repo URL or any other volatile information). So this
#     script may fail if you're doing improbable stuff like rebasing
#     your repo and removing the initial commit.
#
# How it saves an item:
#
#   - Find all git configurations.
#   - Make a backup at $BASE/$ID/config.$DATE if config differs.
#   - Save the config at $BASE/ID.
#
# How it restore an item:
#
#   - Copy each config from $BASE/ID, if available and if it differs.
#   - Restore always save a timestamped copy at .git/config.$DATE.

# Parameters
BASENAME="`basename $0`"
BASE="$HOME/.config/gitconfigs"
DATE="`date +%Y%m%d%I%M%S`"
FILENAME="gitconfig.saved"
OPTION="$1"
COUNTER="$BASE/counter"
SOMETIMES="20"

# Ensure we have a base and that is minimally safe
mkdir -p  $BASE
chmod 700 $BASE

# Save config from a repository
function git_config_save {
  # Check if we have a config
  if [ ! -e ".git/config" ]; then
    echo "$BASENAME: missing config at `pwd`"
    return
  fi

  # Repository ID
  # https://stackoverflow.com/questions/34874343/how-can-i-uniquely-identify-a-git-repository
  #ID="`git rev-list --parents HEAD | tail -1`"
  ID="$PWD"

  # Display ID
  #echo $ID

  # Create config folder
  mkdir -p $BASE/$ID

  # Make a backup
  if [ -f "$BASE/$ID/$FILENAME" ] && ! diff .git/config $BASE/$ID/$FILENAME &> /dev/null; then
    echo "Differences detected at `pwd`, making a backup..."
    cp $BASE/$ID/$FILENAME $BASE/$ID/$FILENAME.$DATE
  fi

  # Save
  cp .git/config $BASE/$ID/$FILENAME
}

# Restore config tor a repository
function git_config_restore {
  # Check if we have a config
  if [ ! -e ".git/config" ]; then
    echo "$BASENAME: missing config at `pwd`"
    return
  fi

  # Repository ID
  # https://stackoverflow.com/questions/34874343/how-can-i-uniquely-identify-a-git-repository
  #ID="`git rev-list --parents HEAD | tail -1`"
  ID="$PWD"

  # Display ID
  #echo $ID

  # Create config folder
  mkdir -p $BASE/$ID

  # Check if we have a saved config
  if [ ! -f "$BASE/$ID/$FILENAME" ]; then
    echo "No config for `pwd`, skipping"
    return
  fi

  # Make a backup
  if ! diff .git/config $BASE/$ID/$FILENAME &> /dev/null; then
    cp .git/config .git/config.$DATE
  else
    echo "Identical configs for `pwd`, skipping"
    return
  fi

  # Restore
  cp $BASE/$ID/$FILENAME .git/config

  # Tell the user about the backup
  echo "Backup saved at $pwd/.git/config.$DATE"
}

# Check option
if [ ! -z "$OPTION" ] && [ "$OPTION" == "--sometimes" ]; then
  if [ ! -e "$COUNTER" ]; then
    echo 0 > $COUNTER
  fi

  COUNT="`cat $COUNTER`"

  if (($COUNT >= $SOMETIMES)); then
    echo 0 > $COUNTER
  else
    let COUNT++
    echo $COUNT > $COUNTER
    echo "Running only sometimes. This is run ${COUNT} of ${SOMETIMES}, skipping."
    exit 1
  fi
fi

# Process everything we can find
find -type d -name .git | while read repo; do
  # Get absolute folder
  PWD="`cd $repo/.. &> /dev/null && pwd`"

  #echo -n -e "Processing $PWD...\t"
  echo "Processing $PWD..."

  (
  cd $PWD

  if [ "$BASENAME" == "git-config-save" ]; then
    git_config_save
  else
    git_config_restore
  fi
  )
done