git push origin HEAD~1:master
This pushes the next-to-last commit (and those prior) to origin/master.
git push origin HEAD~1:master
This pushes the next-to-last commit (and those prior) to origin/master.
git config --global pull.rebase true git config --global rebase.autoStash true
$ pip install git-filter-repo # official recommendation
$ git filter-repo --filename-callback 'return filename if b"filename.zip" not in filename else None' \
--prune-empty=always --force
git update-index --chmod=+x twerk/*.pyCheck your change:
git status --porcelain=2
git push -f origin masterThen on other machine:
git fetch git reset --hard origin/master
git log -p b3503535:path/to/file.cpp 1f3c4a34:path/to/file.cpp
git config --global core.pager "less -F -X"
Only attempt this if you haven't pushed yet.
git rebase --onto HEAD~2 HEAD~1 HEAD git cherry-pick ORIG_HEAD~1 git log -1
Copy the the <SHA1>.
git checkout master git reset --hard <SHA1>
git checkout -b topic123 git commit -a git push --set-upstream origin topic123
git config --system core.autocrlf false git filter-branch -f --prune-empty --tree-filter 'git ls-files -z | xargs -0 dos2unix' -- --all git config --system core.autocrlf true echo '* text=auto' >> .gitattributesBut only as a reaction to things gone bad. As a general rule of thumb, always start your git projects/imports by:
git config core.autocrlf true echo '* text=auto' >> .gitattributes
alias loc='find . |grep -E '"'"'\.(h|hpp|c|cc|cpp|py|js|css|html|jsp|java|php)$'"'"' | xargs cat | wc -l'
alias projloc='for D in *; do [ -d "${D}" ] && echo $D && cd $D && loc && cd ..; done'
$ git log --pretty=format:'%H: %s' 1cd2d7606bbb4b513c8a9460c24955a44ac85da5: HeliForce: fixed monster truck color variation as a7b4c005498096c5b36d76c99ae694fb217dee1d: Added gaming ideas + improvements. b13baf97a1fd7f8de3fffa2efa369fedf9d025de: Merge branch 'master' of ssh://localhost:2202/~rg 732b03941bdfdc6860bf557bab91eb7371f587b8: - DRY'ed float_health, - added monster trucks + a8af0aa92c03120930241ed12739d474e2cfea9a: Made landings more velocity-dependant and also fi ...Then diff from previous commit to merge commit:
git log -p 732b03941bdfdc6860bf557bab91eb7371f587b8..b13baf97a1fd7f8de3fffa2efa369fedf9d025de
git log -p | git_log_quantity_per_person.pyThe script "git_log_quantity_per_person.py":
#!/usr/bin/env python
import pandas as pd
import sys
goodext = ('java')
removalfactor = 2.0 # Paraphrasing Tolstoy: "nothing can improve a piece of software as much as code removal".
commitfactor = 0.1 # A commit is only as good as it's content.
def score(adds, removes, commits):
return adds + removes*removalfactor + commits*commitfactor
def printflatstats(peopledata):
print('name\tadds\tremoves\tcommits')
for person, changedata in peopledata.items():
print('%s\t%6.i\t%6.i\t%4.i' % (person, changedata['adds'], changedata['removes'], changedata['commits']))
def createdatetable(peopledata, dates):
table = []
headers = ['dates'] + list(peopledata.keys())
table += [headers]
for date in reversed(dates):
datefmt = '%s-%s-%s' % (date.date[:4], date.date[4:6], date.date[6:])
row = [datefmt]
for person in peopledata.keys():
changedata = date.peopledata.get(person)
if changedata:
row += [score(changedata['adds'], changedata['removes'], changedata['commits'])]
else:
row += [0.0]
table += [row]
return table
def transpose(table):
return zip(*table)
def combinemonths(table):
df = pd.DataFrame({c[0]:c[1:] for c in zip(*table)})
df.dates = [d[:7]+'-01' for d in df.dates]
df.dates = pd.to_datetime(df.dates)
df = df.groupby('dates').sum()
return df
def printdatestats(peopledata, dates):
table = createdatetable(peopledata, dates)
table = combinemonths(table)
persons = table.iloc[-13:, :].sum() # last year-ish
persons = persons.sort_values().index[::-1]
table = table[persons]
s = table.reset_index().to_csv(index=False, sep='\t')
print(s)
class CommitDate:
def __init__(self, date):
self.date = date
self.peopledata = {}
def addcommit(peopledata, person):
if not peopledata.get(person):
peopledata[person] = {'adds':0, 'removes':0, 'commits':1}
else:
peopledata[person]['commits'] += 1
def cat(inf):
global goodext
peopledata = {}
dates = []
import signal
signal.signal(signal.SIGINT, signal.SIG_IGN)
try:
linecnt = 0
goodfile = False
for line in inf:
line = line.strip()
if line.startswith('Author:'):
goodfile = False
person = line.partition(' ')[2].partition('<')[0].strip()
if line.startswith('Date:'):
goodfile = False
dateline = line.split()
#print(dateline)
month, day, year = dateline[2], dateline[3], dateline[5]
#print(month)
month = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec').index(month) + 1
day = int(day)
year = int(year)
date = '%.4i%.2i%.2i' % (year, month, day)
if len(dates) <= 0 or dates[-1].date != date:
dates.append(CommitDate(date))
addcommit(peopledata, person)
addcommit(dates[-1].peopledata, person)
if line.startswith('+++ ') or line.startswith('--- '):
if line.endswith('/dev/null'):
continue
ext = line.rsplit('.', 1)[-1].lower()
goodfile = (ext in goodext)
#if not goodfile:
# print('Not counting extension', ext)
if not goodfile:
continue
elif line[:1] == '+':
peopledata[person]['adds'] += 1
dates[-1].peopledata[person]['adds'] += 1
elif line[:1] == '-':
peopledata[person]['removes'] += 1
dates[-1].peopledata[person]['removes'] += 1
else:
continue
linecnt += 1
if linecnt % 10000 == 0:
print('.', file=sys.stderr)
except KeyboardInterrupt:
pass
return peopledata, dates
if __name__=='__main__':
import codecs
sys.stdin = codecs.getreader('utf8')(sys.stdin.detach(), errors='ignore')
peopledata, dates = cat(sys.stdin)
print()
print()
printflatstats(peopledata)
print()
printdatestats(peopledata, dates)
Two tables are printed: one flat and one over time. Cut'n'paste into Excel and you're done.
$ git checkout master $ git checkout --patch abc [Confirm all patches with a[ENTER].] $ git commit $ git merge main
$ git status --porcelain | awk '/^.D .*$/ {print $2}' | xargs git rm
$ mkdir project $ cd project $ git init $ git remote add -t the_branch -f origin ssh://whoever@host.com:1234/~/blah.git $ git checkout the_branch
$ git config --global rerere.enabled 1
$ git branch my_fix $ git checkout my_fix [edit] $ git commit -a $ git format-patch HEAD~1 --stdout >my_fix.patchOr if you don't want to save this commit at all, revert after creating patch:
git reset --hard HEAD~1(Committing is good for storing the commit message.) Transfer my_fix.patch to someone who does:
$ git am my_fix.patch
#!/usr/bin/env python
import sys
data = open(sys.argv[-1]).read()
ascii = data.decode('utf-16').encode('ascii', 'replace')
sys.stdout.write(ascii)
Shell:
$ echo "*.strings diff=xcode_strings" >> .gitattributes $ git config diff.xcode_strings.textconv /path/to/utf16_to_ascii.py
$ cd my_submodule
$ git checkout -b topic
[edit]
$ git push origin HEAD (push submodule first)
$ cd ..
$ git commit -a
$ git push origin (push main repo afterwards)
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch my_file'
$ git pull origin
$ git checkout topic_which_introduce_submodule
$ git submodule init
$ git submodule update
$ mkdir my_mod
$ cd my_mod
$ git init
[copy/edit]
$ git commit -a -m "Starting work on my module - yey!"
[create+push to remote, say ssh://domain.com/abc/my_mod.git]
$ cd ..
git submodule add ssh://domain.com/abc/my_mod.git my_mod
[drop stuff no longer needed]
git commit
$ git log --all <file>
commit ff76f5235b46b7d488ded2c51361ad93ecf68136
commit f9cb7762267becb9136a24f208982680b12ba631
commit 53e81e63f13f7569e7118a58c4f9ca2b4b731dc3
$ git branch --contains f9cb7762267becb9136a24f208982680b12ba631
$ git log
$ git checkout -b my_squash
$ git reset --soft <commit before your squashables>
$ git commit
git cherry-pick cc9cdf189d1eb111ecda5fe7916347edea6025a6Only use this when you don't want to merge the branch you're picking from. The most important reason for this is that merging retains commit SHA-1s, but cherry-picking does not; thus you lose tracability.
$ git checkout master(I actually branched before rebasing to avoid rebase mistakes; nonetheless.) If you want to cherry-pick without committing it to the head of your current branch use
$ git checkout -b my_feature_squash
$ git cherry-pick abc
$ git cherry-pick cde
<I edited a file>
$ git commit -a
$ git rebase -i HEAD~4
$git cherry-pick -n cc9cdf189d1eb111ecda5fe7916347edea6025a6
git log topic@{e949f8c63c1df7059939199937a257d957fa3671}The previous commit is actually shown first (concatenate a ^ to the refspec to skip).
[alias]which allows you to
search = log --source --all -p --decorate=full -G
$ git search MyCall\\\(true\\\)This will help you find your commit in any branch.
git clone ssh://...
cd my_project
git branch -a
* master
origin/master
origin/blahblah
git checkout -b blahblah origin/blahblah
function show_git_branch {
echo -n `git branch --no-color 2> /dev/null | sed -e '/^[^*] /d' -e 's/* \(.*\)/\1/'`
}
function has_local_changes {
if ! git diff-files --quiet 2> /dev/null; then
echo -n '*'
fi
if ! git diff-index --cached --quiet HEAD 2> /dev/null; then
echo -n '!'
fi
}
function has_push {
HAS=`git rev-list -n 1 HEAD@{upstream}..HEAD 2> /dev/null`
if [ "$HAS" != "" ]; then
echo -n '->'
fi
}
function show_git_info {
if git rev-parse --git-dir > /dev/null 2>&1; then
echo -ne "\033[0;32m ("
show_git_branch
echo -ne "\033[1;37m"
has_local_changes
has_push
echo -ne "\033[0;32m)"
fi
}
function proml {
local LIGHT_BLUE="\[\033[0;94m\]"
local RED="\[\033[0;31m\]"
local RESET="\[\033[0;0m\]"
case $TERM in
xterm*)
TITLEBAR='\[\033]0;\u@\h:\w\007\]'
;;
*)
TITLEBAR=""
;;
esac
PS1="${TITLEBAR}\
$LIGHT_BLUE\$(date +%H:%M:%S) \
$RED\u@\h:\w\$(show_git_info) \
$RESET\$ "
PS2='> '
PS4='+ '
}
proml
Original thanks to Chris Wanstrath.
git commit --amend
git reset --hard HEAD~1
git add/rm file
git commit --amend
git reset --mixed HEAD~1
git checkout -- fileTo throw everything away since last commit:
git reset --hardTo delete untracked files and directories:
git clean -f -d
./.git/configStuff I usually squeeze in there:
~/.gitconfig
/etc/gitconfig
[core]I also put the following in ./.gitattributes, which go into the repo:
# Use under Windows:
autocrlf = true
# Use under *nix:
autocrlf = input
hideDotFiles = dotGitOnly
[alias]
ca = commit -a
nb = checkout -b
quicklog = log --pretty=format:\"%h %cr %cn %Cgreen%s%Creset\"
logdiff = log -p --stat
search = log --source --all -p --decorate=full -G
* text=auto
cd /directory/to/On local machine:
mkdir my_project.git
cd my_project.git/
git --bare init
cd my_project
git init
git add *
git commit -m "Started working on saving the world."
git remote add origin ssh://user@my.server.com:port/directory/to/my_project.git
git push --set-upstream origin master
git fetch some_repo
git branch -r --contains xyz
>>> some_repo/feature_123
>>> some_repo/integration_x
>>> some_repo/bug_abc