Lore

If it's worth remembering, it's worth writing down, if I find the time, and remember...

User Tools

Site Tools


git

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
git [2018/05/09 09:39] – [Moving Content] thekojukinatorgit [2019/05/08 16:08] (current) – [PowerShell Visual Studio Code Template] thekojukinator
Line 7: Line 7:
   * https://www.atlassian.com/git/tutorials - More great tutorials here.   * https://www.atlassian.com/git/tutorials - More great tutorials here.
   * https://help.github.com - GitHub documentation.   * https://help.github.com - GitHub documentation.
 +  * https://guides.github.com/features/mastering-markdown - Markdown reference.
  
 I was using ''git version 2.16.2.windows.1'' in the //Bash// shell while documenting and testing these commands. I was using ''git version 2.16.2.windows.1'' in the //Bash// shell while documenting and testing these commands.
Line 16: Line 17:
 For further configuration options, see the [[https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration| Git documentation]]. For further configuration options, see the [[https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration| Git documentation]].
  
-=== Set name and e-mail address for commits ===+==== Contact Info for Commits ====
  
 <code bash> <code bash>
Line 23: Line 24:
 </code> </code>
  
-=== Set handling of line endings ===+==== Handling Line Endings ====
  
 <code bash> <code bash>
Line 34: Line 35:
 </code> </code>
  
-=== Set alias for pretty log output ===+A complementary setting in //Visual Studio Code// when developing on Windows is to enforce CRLF. 
 + 
 +<code css settings.json> 
 +
 +    // this assumes Windows dev environment with Git config option "core.autocrlf=true" 
 +    "files.eol": "\r\n" 
 +
 +</code> 
 +==== Pretty Log Alias ====
  
 More helpful aliases are demonstrated [[https://githowto.com/aliases|here]]. More helpful aliases are demonstrated [[https://githowto.com/aliases|here]].
  
 This log command will give nice and pretty output: This log command will give nice and pretty output:
 +
 <code bash> <code bash>
 git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
 +# or without pagination
 +git --no-pager log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
 </code> </code>
  
 It can be configured in to a global alias like so: It can be configured in to a global alias like so:
 +
 <code bash> <code bash>
 git config --global alias.hist "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short" git config --global alias.hist "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
 +# unfortunately these won't work...
 +git config --global alias.hist "--no-pager log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
 +git config --global alias.hist "!git --no-pager log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
 +# but, this will disable pagination for all calls to 'log'
 +git config --global pager.log false
 +
 +# I've recently discovered some prettier log outputs, so my .gitconfig aliases are like so...
 +hist = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
 +hist1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'
 +hist2 = log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short
 +# first two are courtesy of https://stackoverflow.com/a/9074343
 </code> </code>
  
 So now it's simply enough to do: So now it's simply enough to do:
 +
 <code bash> <code bash>
 git hist git hist
Line 55: Line 80:
 </code> </code>
  
-=== Visual Studio Code as Git editor and diff tool ===+==== VSCode as Editor and Diff Tool ====
  
 More info [[https://code.visualstudio.com/docs/editor/versioncontrol|here]] about //Git// integration with //Visual Studio Code//. More info [[https://code.visualstudio.com/docs/editor/versioncontrol|here]] about //Git// integration with //Visual Studio Code//.
  
 Set //Visual Studio Code// as the default //Git// editor, and configure it to wait for the editor to close before continuing: Set //Visual Studio Code// as the default //Git// editor, and configure it to wait for the editor to close before continuing:
 +
 <code bash> <code bash>
 git config --global core.editor "code --wait" git config --global core.editor "code --wait"
Line 65: Line 91:
  
 Now it's possible to edit the //Git// config in //Visual Studio Code// like so: Now it's possible to edit the //Git// config in //Visual Studio Code// like so:
 +
 <code bash> <code bash>
 git config --global -e git config --global -e
Line 70: Line 97:
  
 Leveraging the above, add the following to ''.gitconfig'': Leveraging the above, add the following to ''.gitconfig'':
 +
 <code> <code>
 [diff] [diff]
Line 83: Line 111:
 git config -l git config -l
 # show global settings only # show global settings only
 +# these live in the user profile
 git config --global -l git config --global -l
 # show system settings only # show system settings only
 +# these live in the git installation path
 git config --system -l git config --system -l
-# show repo settings only (must be in repo folder)+# show local settings only 
 +# these live in the repo
 git config --local -l git config --local -l
 </code> </code>
Line 95: Line 126:
  
 Create a **repo** in the current folder: Create a **repo** in the current folder:
 +
 <code bash> <code bash>
 git init git init
Line 100: Line 132:
  
 Create a **repo** in the folder ''MyRepo''(folder will be created if it doesn't exist): Create a **repo** in the folder ''MyRepo''(folder will be created if it doesn't exist):
 +
 <code bash> <code bash>
 git init MyRepo git init MyRepo
Line 105: Line 138:
  
 From the parent folder, it's possible to clone a **repo** with: From the parent folder, it's possible to clone a **repo** with:
 +
 <code bash> <code bash>
 git clone <origin> <dest> git clone <origin> <dest>
Line 113: Line 147:
 NOTE: A cloned **repo** will have a single ''master'' **branch** and remote **branches** tracked from the origin **repo**. NOTE: A cloned **repo** will have a single ''master'' **branch** and remote **branches** tracked from the origin **repo**.
  
-=== Bare Repos ===+==== Bare Repos ====
  
 Doing ''git init'' or ''git clone'' commands with the ''--bare'' switch will make a **repo** without a working directory, only //Git// data. A **bare repo** is intended for sharing (fetch/push/pull) only. Doing ''git init'' or ''git clone'' commands with the ''--bare'' switch will make a **repo** without a working directory, only //Git// data. A **bare repo** is intended for sharing (fetch/push/pull) only.
Line 130: Line 164:
 ===== Multiple Repos ===== ===== Multiple Repos =====
  
-=== Syncing ===+==== Syncing ====
  
 Commits are pulled down from a remote **repo** via ''git fetch'', however this doesn't automatically merge them in to the local **branches**. Commits are pulled down from a remote **repo** via ''git fetch'', however this doesn't automatically merge them in to the local **branches**.
Line 142: Line 176:
  
 However, [[#merging]] remote fetched commits is the same as any other commits. This will merge all the commits from ''origin/master'' in to the currently checked out **branch**: However, [[#merging]] remote fetched commits is the same as any other commits. This will merge all the commits from ''origin/master'' in to the currently checked out **branch**:
 +
 <code bash> <code bash>
 git merge origin/master git merge origin/master
Line 166: Line 201:
 If, as mentioned in [[#managing remote repos]], local **branches** are already configured to track remote **branches**, it shouldn't be necessary to specify any parameters. Simply running ''git push'' should be enough. If, as mentioned in [[#managing remote repos]], local **branches** are already configured to track remote **branches**, it shouldn't be necessary to specify any parameters. Simply running ''git push'' should be enough.
  
-=== Tracking Branches ===+==== Tracking Branches ====
  
 When a **repo** is cloned, the only local **branch** is ''master'', and while the other remote **branches** are tracked, ''git pull'' and ''git push'' are only setup between the local and remote ''master'' **branches**. This can be confirmed by reviewing the remote configuration. When a **repo** is cloned, the only local **branch** is ''master'', and while the other remote **branches** are tracked, ''git pull'' and ''git push'' are only setup between the local and remote ''master'' **branches**. This can be confirmed by reviewing the remote configuration.
Line 180: Line 215:
  
 It is possible to create a local **branch** that tracks commits from a remote **branch**: It is possible to create a local **branch** that tracks commits from a remote **branch**:
 +
 <code bash> <code bash>
 # create a new localbranch to track remotebranch # create a new localbranch to track remotebranch
Line 188: Line 224:
  
 It is also possible to modify an existing local **branch** and set it to track commits from a remote **branch**: It is also possible to modify an existing local **branch** and set it to track commits from a remote **branch**:
 +
 <code bash> <code bash>
 # for currently checked out branch # for currently checked out branch
Line 206: Line 243:
 </code> </code>
  
-=== Managing Remote Repos ===+==== Managing Remote Repos ====
  
 <code bash> <code bash>
Line 213: Line 250:
 # ex: # ex:
 git remote add origin ../folder git remote add origin ../folder
 +# remove remote repo
 +git remote rm <reponame>
 +# ex:
 +git remote rm origin
 +</code>
  
 +With ''git push -u'' it's possible accomplish the same things as ''git branch -u'', the latter being more specific in how to link **branches**.
 +
 +<code bash>
 # configure branchname to track remote branchname on reponame # configure branchname to track remote branchname on reponame
 git push -u <reponame> <localbranch> git push -u <reponame> <localbranch>
Line 221: Line 266:
 # alternatively, this will do above for all branches # alternatively, this will do above for all branches
 git push -u --all git push -u --all
 +</code>
  
 +When a **repo** is cloned, remote ''HEAD'' tracking is configured automatically. When setting up remote **repos** manually it's possible to do this with ''git remote set-head''.
 +
 +<code bash>
 # set reponame/HEAD as master # set reponame/HEAD as master
 git remote set-head <reponame> -a git remote set-head <reponame> -a
Line 230: Line 279:
 # ex: # ex:
 git remote set-head origin -d git remote set-head origin -d
 +</code>
  
-# remove remote repo +In some cases it may be desired to disable ''git push'' and effectively setup a pull only **repo**. There is no official disable switch, but it's possible to provide a bogus URL that will generate an error. 
-git remote rm <reponame>+ 
 +<code bash> 
 +# set the remoterepo push url 
 +git remote set-url --push <remoterepo> <url>
 # ex: # ex:
-git remote rm origin+git remote set-url --push origin DISABLE
 </code> </code>
  
-NOTE: It's possible to accomplish the same things with ''git push -u'' and ''git branch -u'', the latter being more specific in how to link **branches**.+To track certain remote **branches** use ''git remote set-branches''. Using the ''--add'' switch will append the current configuration, otherwise it will be replaced. 
 + 
 +<code bash> 
 +# track only <remoterepo> <remotebranch> 
 +git remote set-branches <remoterepo> <remotebranch> 
 +# ex: 
 +git remote set-branches origin master 
 +# whoops, also want to track dev1 branch 
 +git remote set-branches --add origin dev1 
 +</code> 
 + 
 +When a tag is removed from the local **repo** it will not be removed from the remote **repo** via standard ''git push'' or even ''git push --all'', but there is a way to do it. 
 + 
 +<code bash> 
 +# delete <tag> from <remoterepo> 
 +git push <remoterepo> :<tag> 
 +# ex: 
 +git push origin :v1.0 
 +</code> 
 + 
 +Alternatively, if new tags were created but there are no new commits, it's possible to push the tags to the remote **repo** via ''git push --tags''.
  
 ===== Stage, Confirm, Commit, and Tag ===== ===== Stage, Confirm, Commit, and Tag =====
Line 244: Line 317:
  
 Stage files: Stage files:
 +
 <code bash> <code bash>
 # a single file # a single file
Line 258: Line 332:
  
 Confirm **repo** status: Confirm **repo** status:
 +
 <code bash> <code bash>
 git status git status
Line 263: Line 338:
  
 Commit changes: Commit changes:
 +
 <code bash> <code bash>
 # commit and launch default editor to provide comment # commit and launch default editor to provide comment
Line 274: Line 350:
   * Stage the necessary files   * Stage the necessary files
   * Perform a new commit with the ''--amend'' switch   * Perform a new commit with the ''--amend'' switch
 +
 <code bash> <code bash>
 git commit --amend -m "Commit comment" git commit --amend -m "Commit comment"
Line 279: Line 356:
  
 Tag commits for easier management: Tag commits for easier management:
 +
 <code bash> <code bash>
 # tag the current commit with a friendly name # tag the current commit with a friendly name
Line 304: Line 382:
  
 This is not an undo, but instead of checking out files, it's possible to checkout a commit via the first 7 digits of the hash (from ''git hist'' if the [[#set alias for pretty log output|alias]] is defined), or tags: This is not an undo, but instead of checking out files, it's possible to checkout a commit via the first 7 digits of the hash (from ''git hist'' if the [[#set alias for pretty log output|alias]] is defined), or tags:
 +
 <code bash> <code bash>
 git checkout <hash> git checkout <hash>
Line 311: Line 390:
  
 To return to the latest commit do: To return to the latest commit do:
 +
 <code bash> <code bash>
 git checkout <branch> git checkout <branch>
Line 318: Line 398:
  
 Staged changes can be rolled back via ''git reset''. Staged changes can be rolled back via ''git reset''.
 +
 <code bash> <code bash>
 # unstage all currently staged changes # unstage all currently staged changes
Line 328: Line 409:
  
 NOTE: The working directory still has modified and unstaged files, use ''git checkout'' to replace them with committed version: NOTE: The working directory still has modified and unstaged files, use ''git checkout'' to replace them with committed version:
 +
 <code bash> <code bash>
 git checkout . git checkout .
Line 337: Line 419:
  
 This will cancel wherever ''HEAD'' is, which is usually the last commit: This will cancel wherever ''HEAD'' is, which is usually the last commit:
 +
 <code bash> <code bash>
 git revert HEAD git revert HEAD
Line 344: Line 427:
  
 To revert the working directory to a specified commit, and remove all later commits from history: To revert the working directory to a specified commit, and remove all later commits from history:
 +
 <code bash> <code bash>
 git reset --hard <hash> git reset --hard <hash>
Line 351: Line 435:
  
 NOTE: If removed commits had tags, those tags need to be removed or the commits will remain in history. This can be done after ''git reset'': NOTE: If removed commits had tags, those tags need to be removed or the commits will remain in history. This can be done after ''git reset'':
 +
 <code bash> <code bash>
 git tag -d BadVersion git tag -d BadVersion
Line 387: Line 472:
 Branches are managed via ''git branch'', switched via ''git checkout'', and merged via ''git merge''. Branches are managed via ''git branch'', switched via ''git checkout'', and merged via ''git merge''.
  
-=== Create, List, Checkout, and Delete ===+==== Create, List, Checkout, and Delete ====
  
 <code bash> <code bash>
Line 408: Line 493:
 </code> </code>
  
-=== Merging ===+==== Merging ====
  
 <code bash> <code bash>
Line 418: Line 503:
 </code> </code>
  
-=== Rebasing ===+==== Rebasing ====
  
 Branches can be rebased with ''git rebase''. Rebasing merges the **branch** histories in to a single thread, effectively performing a merge and then flattening the commit tree. Branches can be rebased with ''git rebase''. Rebasing merges the **branch** histories in to a single thread, effectively performing a merge and then flattening the commit tree.
Line 431: Line 516:
  
 NOTE: Rebasing can get tricky in some scenarios and cause issues, check the documentation for further details: NOTE: Rebasing can get tricky in some scenarios and cause issues, check the documentation for further details:
 +
 <code bash> <code bash>
 git rebase --help git rebase --help
 +</code>
 +
 +===== Ignoring Content =====
 +
 +It's possible to tell //Git// to ignore files and/or folders by using a ''.gitignore'' file.
 +
 +See the following for more details and examples:
 +  * https://git-scm.com/docs/gitignore - official documentation.
 +  * https://www.gitignore.io - great tool for getting a quick and simple starting template.
 +  * https://www.atlassian.com/git/tutorials/saving-changes/gitignore - more examples here.
 +  * https://jasonstitt.com/gitignore-whitelisting-patterns - a helpful blog post.
 +
 +<code git .gitignore>
 +# matching is done on the whole path string, so
 +# this will ignore everything regardless of depth
 +*
 +# whatever exceptions are made, will only work in
 +# the current folder, unless recursion is allowed with
 +!*/
 +# this will whitelist at the top level
 +!*.ps1
 +# this will whitelist everywhere
 +!**/*.xml
 +# lines are processed in order, so it's possible
 +# to undo everything above with
 +!*
 +</code>
 +
 +==== PowerShell Visual Studio Code Template ====
 +
 +This is my baseline template for starting a //PowerShell// project in //Visual Studio Code//. It's effectively a white-list.
 +
 +<code git .gitignore>
 +# ignore everything eveywhere
 +*
 +
 +# allow folder recursion
 +!*/
 +
 +# allow .git* at top level
 +!.git*
 +
 +# allow .md at top level
 +!*.md
 +
 +# whitelist VSCode settings at the top level
 +!/.vscode/settings.json
 +
 +# whitelist contents of these folders at the top level
 +!/ProjectFolderContainingAllTheGoodies/**
 +
 +# regardless of above, ignore these folders and files everywhere
 +**/_logs*
 +**/_testing*
 +
 +</code>
 +
 +Here is a template generated by [[https://www.gitignore.io|gitignore.io]] for //PowerShell//, //Visual Studio Code//, and //Windows//.
 +
 +<code git .gitignore>
 +# Created by https://www.gitignore.io/api/windows,powershell,visualstudiocode
 +
 +### PowerShell ###
 +# Exclude packaged modules
 +*.zip
 +
 +# Exclude .NET assemblies from source
 +*.dll
 +
 +### VisualStudioCode ###
 +.vscode/*
 +!.vscode/settings.json
 +!.vscode/tasks.json
 +!.vscode/launch.json
 +!.vscode/extensions.json
 +.history
 +
 +### Windows ###
 +# Windows thumbnail cache files
 +Thumbs.db
 +ehthumbs.db
 +ehthumbs_vista.db
 +
 +# Folder config file
 +Desktop.ini
 +
 +# Recycle Bin used on file shares
 +$RECYCLE.BIN/
 +
 +# Windows Installer files
 +*.cab
 +*.msi
 +*.msm
 +*.msp
 +
 +# Windows shortcuts
 +*.lnk
 +
 +# End of https://www.gitignore.io/api/windows,powershell,visualstudiocode
 </code> </code>
  
 {{tag>computing git}} {{tag>computing git}}
git.1525873172.txt.gz · Last modified: 2018/05/09 09:39 by thekojukinator