-
Notifications
You must be signed in to change notification settings - Fork 0
/
git.txt
648 lines (461 loc) · 20.9 KB
/
git.txt
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
#!/bin/sh
#---------------------------------------------------------
# Ref
#---------------------------------------------------------
ref:
* ref is anything pointing to a commit,
for example branches aka heads, tags, remote branches
* An indirect way of referring to a commit.
A human readable name for a commit hash
* Refs are stored as normal text files in the .git/refs directory
convert a commit hash to reference:
git show 0c708f
convert a reference to commit hash:
git rev-parse main
convert long commit hash to short form
git rev-parse --short <long commit hash>
convert short hash to full SHA-1 reference
git rev-parse <short hash>
#---------------------------------------------------------
# commit references
#---------------------------------------------------------
HEAD : last commit
HEAD^ : parent of HEAD. same as HEAD~
HEAD~3 : The fourth last commit. same as HEAD^^^
ORIG_HEAD: The position of HEAD just before "pull" or "merge"
^refC : not refC: e.g. all commits reachable from refB
but not from refC "git log ^refA refB"
#---------------------------------------------------------
# TODO
#---------------------------------------------------------
reflog syntax
stash@{0} most recently created stash
stash@{0} the one before stash@{0}
stash@{2.hours.ago}
#---------------------------------------------------------
# init
#---------------------------------------------------------
# initialize a bare (shared) repository
mkdir newproj.git
chown -R git:git newproj.git
chmod -R ug+rwX newproj.git/
cd newproj.git
git init --bare
git config core.sharedRepository group
chgrp -R git .
chmod -R g+rwX .
sudo usermod -a -G git aawais
#---------------------------------------------------------
# Remote
#---------------------------------------------------------
# clone a remote repository
git clone [url] [local-directory-name]
# connect repository to a remote server.
git remote add origin <server>
git remote add pb https://github.com/paulboone/ticgit
# What are my remotes
git remote -v
# Fetch from a particular remote
git fetch [remote-name]
# Rename, Remove remote
git remote rename pb paul
git remote rm paul
# change remote repository, eg to change from https to ssh
git remote set-url origin git@github.com:aliawa/dotfiles.git
#---------------------------------------------------------
# Log
#---------------------------------------------------------
git log -- Makefile # see change log of one file:
git log <branch> # show commits going back from a specific branch
git log . # show changes in current directory only
git log --patch # log with patch
git log -Sfunc_name # which commit added or removed the function
# see change log from a date to a date
git log --since="2 weeks ago" --until="yesterday"
git log master..ver_13_11_x_br # all commits in 13_11_x_br that are not in master
git log ver_13_11_x..master # all commits in master that are not in 13_11_x_br
# all tags and branches on 11_6_4_br not reachable from master
git log --simplify-by-decoration master..ver_11_6_4_br
git log --author=aawais # by user
git log --name-status # show only files that have changed
# search in log messages
git log --grep='Bug.*11197'
# match by author and grep (all-match: match all conditions)
git log --author=aawais --grep=time_t --all-match
--abbrev-commit the commit id is shortened
--patch show diff output (-p)
--output=<file> send log output to a file
--oneline shorthand for "--pretty=oneline --abbrev-commit"
#---------------------------------------------------------
# History
#---------------------------------------------------------
# show current branch only
git show-branch --more=20
# restoring a directory from history
git checkout <treeish> -- /path/to/dir
git checkout ver_13_6_0 mand
#---------------------------------------------------------
# Branching
#---------------------------------------------------------
### create
git branch foo # create a branch at last commit
git branch foo <starting-commit> # start a branch from any point
git switch -c foo # create a branch and switch to it
git switch -c foo -m
git stash branch <new_branch_name> # create a branch from stashed changes, starting the branch from commit at which stash was created
### switch
git switch master # switch to branch master
### delete a branch
git branch -d test_br
### push
# First time checkin of a branch (to remote with alias 'origin', check with 'git remote -v'
git push -u origin dbr_aaw_em9459
# Push the branch to remote repository
git push [remote-name] [branch-name] # General Syntax
git push origin <branch>
### info
git branch -r # show all remote branches
git branch -r --list 'origin/ver_11_6_*' # List remote branches matching pattern
git branch -vv # More info about all local branches
git merge-base master origin/ver_14_0_x_br # show starting point of branch made on master
### merging
git merge test_merge # merge another branch with the current branch
# Merging from a developer branch using rebase (four steps)
git checkout dbr_aaw_em9459
git rebase master
git checkout master
git merge dbr_aaw_em9459
#---------------------------------------------------------
# Pull
#---------------------------------------------------------
# git checkout by date
git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`
#---------------------------------------------------------
# Diff
#---------------------------------------------------------
git diff # worktree and staged
git diff --stat [branch] # only show changed files| No. of lines changed| graph
git diff --staged # staged and last-commit
#
# diff between working dir and commited files
# for last commit use HEAD
git diff <hash> -- <filename>
# diff between two historical versions
git diff <hash1> <hash2> -- <filename>
# Usefull options
--name-only # show names of files that have changed
--name-status # Modified/Added/Deleted | name of changed file
--stat # name of file changed | No. of lines changed | graph
# diff with an earlier version of file and working directory
git diff 2a076af:mand/b2buaInviteCore.cpp b2buaInviteCore.cpp
==> see man git-diff > EXAMPLES
#---------------------------------------------------------
# Checkin and Staging
#---------------------------------------------------------
# Send files to staging area (same as git add)
git stage <files>
# Adding changes to the staging area. Hunk by Hunk
git stage --patch models.rb
# checkin a file (2 step process)
git stage <file>
git commit
# auto stage modified and deleted files but not new files and then commit
git commit -a
# prevent files from being checked in
git update-index --assume-unchanged cfg_sip.h
git update-index --no-assume-unchanged cfg_sip.h
# what am i about to push
git log origin/master..HEAD
git log origin/master.. #HEAD is default
#---------------------------------------------------------
# Patch
#---------------------------------------------------------
# create patch
git diff > ~/tmp/mypatch
# Apply a patch using git (Atomic, handles file rename, delete etc.)
git apply ~/tmp/mypatch
git apply -v ~/tmp/mypath # to check why a patch failed
# Remove a patch ie undo change
git apply -R <patch>
# create patch from single commit
git show -p 06b6f75e > ~/tmp/a.patch
# patch from single commit
git format-patch -1 3c2ab26f8ae --stdout
#---------------------------------------------------------
# OOPS / UNDO
#---------------------------------------------------------
# Undo last commit
git reset --soft HEAD^ # not pushed yet
git revert HEAD # when it has already been pushed
# Add more changes to last commit
git add sipClient.h
git commit --amend
# change the last commit message
git commit --amend
# revert next-to-last commit but keep the last commit
git revert HEAD^
# replace working file with an old one
git checkout HEAD^ path/to/file
# change log message of previous commit (i.e.,) not most recent one
# execute command below then pick the change, you need to edit
# the commit messsage for.
git rebase -i HEAD~2
#---------------------------------------------------------
# Tags
# Tags Always point to the same revision. They do not
# change with commits. As opposed to branch pointer
# which moves forward with commits
#---------------------------------------------------------
git tag -l # show all tags
git tag -l v1.8.5* # list pattern
git tag -a v1.4 -m 'my version 1.4' # create anotated
git show v1.4 # see tag data
git tag v1.4-lw # create lightweigt
git tag -a v1.2 9fceb02 # tag a commit
git push origin v1.5 # sharing tag
git checkout -b version2 v2.0.0 # start a new branch at tag v2.0.0
git tag --contains 34b1413b3863 # which tag contains the given commit
#---------------------------------------------------------
# Settings
#---------------------------------------------------------
# list or cat ~/.gitconfig
git config -l
# set
git config --global diff.external extDiff
# unset
git config --global --unset diff.external
git config --unset branch.autosetuprebase
git config --unset branch.master.rebase
#---------------------------------------------------------
# My Settings
#---------------------------------------------------------
git config --global user.name "Ali Awais"
git config --global user.email "$USER@edgewaternetworks.com"
git config --global color.ui true
git config --global core.excludesfile "$HOME/.gitignore"
git config --global commit.template "$HOME/.gitmessage.txt"
git config --global push.default simple
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.last 'log -1 HEAD'
git config --global alias.unstage 'reset HEAD --'
git config --global branch.autosetuprebase always
git config color.grep.filename "blue reverse"
git config --global alias.g "grep --break --heading --line-number"
git config --global merge.stat true
#---------------------------------------------------------
# Vim related
#---------------------------------------------------------
# Adding vim bundles
cd ~/dotfiles/vim/bundle
git submodule add git://github.com/tpope/vim-fugitive.git vim-fugitive
# Clone a project with submodules
git clone --recurse-submodules https://github.com/aliawa/dotfiles
# -- OR manualy --
git clone https://github.com/aliawa/dotfiles
git submodule init
git submodule update # get the submodule version recorded in main project
# List submodules
git submodule --recursive
git submodule--helper list
# Pulling in upstream changes from the submodule remote
git submodule update --remote DbConnector
# fetch latest code for all submodules
git submodule foreach git pull origin master
# Pulling Upstream Changes from the Project Remote
git pull
git submodule update --init --recursive
# Remove submodule
git rm -r <submodule_folder>
rm -rf .git/modules/<submodule_folder>
git config -f .git/config --remove-section submodule.<submodule_folder>
#---------------------------------------------------------
# Vim related
#---------------------------------------------------------
# Activate spell check in checckin comment
autocmd Filetype gitcommit setlocal spell textwidth=72
# Abort a commit (exit vim with error)
:cq
#---------------------------------------------------------
# Utilities
#---------------------------------------------------------
# Remove all files not known to git (make clean)
git clean -f
# Three way merge
git merge-file -p file.ours file.common file.theirs > file.c
# Binary search
git bisect start
git bisect bad # Current version is bad
git bisect good v1.0 # v1.0 is known to be good
# >> compile and test the checked out versions <<
git bisect bad # This version is also bad
git bisect good # This version is good
# >> continue until first bad commit is found <<
git bisect reset # go back to original head
# >> if you have an automated ./test script that has exit status 0 iff the test is OK <<
# >> then git can automate the process <<
git bisect start <known-bad-commt> <known-good-commit>
git bisect run ./test
# Resolving merge conflicts
git mergetool -t vimdiff
git mergetool -t diffconflicts #<< this one is nicer
#---------------------------------------------------------
# On Line Help
#---------------------------------------------------------
git cheat sheet
http://ndpsoftware.com/git-cheatsheet.html
escape a git mess
http://justinhileman.info/article/git-pretty/git-pretty.png
Book: Git from bottom up
http://ftp.newartisans.com/pub/git.from.bottom.up.pdf
gitignore
http://gitignore.io
A Hacker’s Guide to Git
https://wildlyinaccurate.com/a-hackers-guide-to-git
#---------------------------------------------------------
# git scripts
#---------------------------------------------------------
# create two working directories linked to the same repo
git-new-workdir
# add git command completion to bash
git-completion.bash
#---------------------------------------------------------
# github
#---------------------------------------------------------
For github
git remote set-url origin git@github.com:aliawa/scapy.git
#---------------------------------------------------------
# Git cleanup
#---------------------------------------------------------
From Ben Villalobos guy
git gc
git fsck
git prune
# remove any remote-tracking references that no longer exist on the remote
# This does not remove local branches setup to track remote branches
git fetch --prune
#------------ HEAD and Branch meaning ------------------------------
NOTE that a branch name i.e. a branch label is actually a reference to the
latest commit on a branch or the tip of the branch. In the diagram above,
featureX, master and HEAD are just references to specific commits. featureX and
master labels refer to latest commits on their respective branches. HEAD
generally refers to the tip of the currently checked out branch - master in
this case.
If you checkout an older commit on your current branch, then HEAD
will be in a detached state, i.e., it will point to the older commit instead of
the latest one. Also note that HEAD is called a symbolic reference because it
actually points to the current branch label and any branch label always points
to the tip of the branch. So, under normal circumstances, HEAD indirectly
points to the latest commit.
As an aside, note that Git represents its commit graph/history as a directed
acyclic graph. Each commit has a reference to its parent. Hence, the arrows in
a commit diagram point from child commit to parent commit. We need a reference
to the latest child commit in order to reach the older commits on a branch.
#---------------------------------------------------------
# git reset / git restore
#---------------------------------------------------------
git reset [<mode>] [<commit>]
In all modes the HEAD will be moved to <commit>,
defaults to HEAD when no <commit> specified, in this case the HEAD will not move ofcourse,
but the side-effect determined by <mode> will take place.
mode can have one of five values
--soft
just move the HEAD but leave index and working tree alone
This can for example be used to combine several commits.
git add -A; git commit -m "Start here."
git add -A; git commit -m "One"
git add -A; git commit -m "Two"
git add -A; git commit -m "Three"
git reset --soft HEAD~3
git add -A; git commit -m "All in one"
--hard
move the HEAD and also change index and working tree to match, discarding local changes
--mixed
[default mode] move the HEAD, change index to match it but leave working dir unchanged
so if you do "git reset --mixed HEAD" or just "git reset" this will practically
unstage any staged changes.
this is similar to "git restore --staged ./*"
--merge and --keep
They are similar to hard in that they both update the index and working tree to match
the new HEAD. Differ as follows
1. If there are no staged changes then merge and keep are similar, they
both keep the working tree changes intact.
2. If there are staged changes but no unstaged changes then keep will unstage the
staged changes but merge will discard the staged changes
Example:
# Overwrite local changes
git fetch --all
git reset --hard origin/master
git pull
git restore .
git restore /path/to/file/to/revert
discard unstaged changes. Do not touch index
#---------------------------------------------------------
# Which branch / tag has the commit
#---------------------------------------------------------
git branch --contains f9320513e6a
git tag --contains f9320513e6a # lists all tags that contain the commit
git name-rev --name-only f9320513e6a # The first tag that contained this commit (meaning after this commit)
git describe --all <commit> # The first tag before this commit
git describe --contains <commit> # The first tag after this commit
#---------------------------------------------------------
# Switch
#---------------------------------------------------------
git switch -c foo <start-point> # grow a new branch at start point
git switch -c foo -m <start-pt> # same as above but also merge local changes into the files from swith target
git switch <branch-name> # switch to branch
git switch --discard-changes <branch> # swith to branch and discard all local changes
git switch --detach <commitish> # where committish is tag name or commit number
git switch - # come back to head from detached-head state
# show author, commit message, changed files and diff in a commit
git show 09ce34b9
# show files changed in a commit
git show --pretty="" --name-only head~8
git revisions
----------------------------------------------------------------------
^r1 r2 not reachable from r1 but reachable from r2, i.e., all commits from r1 (not including r1) to r2
r1..r2 same as ^r1 r2
#---------------------------------------------------------
# Worktree
#---------------------------------------------------------
# create new worktree on existing branch
git worktree add <path to folder> <commit-ish> # path is usually like "../folder-name"
# create new worktree with new branch
git worktree add <path to folder> <commit-ish> -b <new-branch-name>
# remove worktree
git worktree remove <path to folder>
git worktree remove --force <path to folder> # loose uncommitted changes
#list
git worktree list # First item is the main worktree, others are linked worktrees
# How to find the main worktree.
In the main worktree .git is a directory in all other worktrees it is a file
file <worktree dir returned by 'git worktree list' command>/.git
# for panOS, run this after creating a new worktree
git submodule update --init --recursive
#---------------------------------------------------------
# commit-ish / tree-ish
#---------------------------------------------------------
Commit-ish/Tree-ish Examples
------------------------ ---------------------------------------
1. <sha1> dae86e1950b1277e545cee180551750029cfe735
2. <describeOutput> v1.7.4.2-679-g3bee7fb
3. <refname> master, heads/master, refs/heads/master
4. <refname>@{<date>} master@{yesterday}, HEAD@{5 minutes ago}
5. <refname>@{<n>} master@{1}
6. @{<n>} @{1}
7. @{-<n>} @{-1}
8. <refname>@{upstream} master@{upstream}, @{u}
9. <rev>^ HEAD^, v1.5.1^0
10. <rev>~<n> master~3
11. <rev>^{<type>} v0.99.8^{commit}
12. <rev>^{} v0.99.8^{}
13. <rev>^{/<text>} HEAD^{/fix nasty bug}
14. :/<text> :/fix nasty bug
Tree-ish only Examples
------------------------ --------------------------------------
15. <rev>:<path> HEAD:README.txt, master:sub-directory/
Tree-ish? Examples
------------------------ --------------------------------------
16. :<n>:<path> :0:README, :README