123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914 |
- Git: distributed version-control system (https://git-scm.com/)
- Git User Manual (git means "unpleasant person" in British English slang)
- file:/usr/share/doc/git/html/user-manual.html
- You can download default github .gitignore files for many programming languages here:
- https://github.com/github/gitignore
- Practicing and Understanding Git - ohmygit.org
- License file - https://choosealicense.com/
- .gitignore file - https://gitignore.io
- Visualizing Git concepts with D3 -
- https://onlywei.github.io/explain-git-with-d3/#commit
- Ref: man gittutorial, gittutorial-2, giteveryday, gitcore-tutorial
- Git is simple to use. Just type git. Without any arguments, Git lists its
- options and the most common subcommands.
- $ git
- For a complete (and somewhat daunting) list of git subcommands, type git help --all.
- $ git help --all
- Git stores configuration options in three separate file, which lets you scope options
- to individual repositories (local), user (global), or the entire system (system):
- * local /.gitconfig - repository-specific settings
- * global /.gitconfig - user-specific settings
- * system /etc/gitconfig - system-wide settings
- View config settings:
- git config --list
- view config settings and the file path:
- git config --list --show-origin
- Git local setup:
- git config --local user.name "Saravanan Dayalan"
- git config --local user.email "dayalsaravanan@gmail.com"
- git config --local core.editor vim
- git config --local color.ui false
- git config --local init.defaultBranch main
- git config --local --edit
- git config --local --list
- git config --local --list --show-origin
- Git global setup:
- git config --global user.name "Saravanan Dayalan"
- git config --global user.email "dayalsaravanan@gmail.com"
- git config --global core.editor vim
- git config --global color.ui fasle
- git config --global init.defaultBranch main
- git config --global --edit
- git config --global --list
- git config --global --list --show-origin
- Git system setup:
- git config --system user.name "Saravanan Dayalan"
- git config --system user.email "dayalsaravanan@gmail.com"
- git config --system core.editor vim
- git config --system color.ui false
- git config --system init.defaultBranch main
- git config --system --edit
- git config --system --list
- git config --system --list --show-origin
- Reference: https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup
- # aliases examples
- git config --global alias.st status
- git config --global alias.co checkout
- git config --global alias.br branch
- git config --global alias.up rebase
- git config --global alias.ci commit
- git help config
- git config --help
- man git-config
- Create a new repository:
- git clone https://gitlab.com/dsaravanan/Books.git
- cd Books
- touch README.md
- git add README.md
- git commit -m "add README"
- git push -u origin main
- Existing folder:
- cd existing folder
- git init
- git remote add origin https://gitlab.com/dsaravanan/Books.git
- git add .
- git commit -m "Initial commit"
- git push -u origin main
- Existing Git repository:
- cd existing repo
- git remote rename origin old-origin
- git remote add origin https://gitlab.com/dsaravanan/Books.git
- git push -u origin --all
- git push -u origin --tags
- # git pull example (git pull does a git fetch followed by a git merge)
- git init .
- git remote add origin https://gitlab.com/dsaravanan/dotfiles.git
- git pull origin main # download all files & commits & overrides in existing repository
- git add <filename>
- git commit -m <commit message>
- git push -u origin main
- git status
- git log | less / git log --stat | less
- git log --pretty=oneline # print the git log messages in oneline
- git branch
- git branch <localbranchname>
- git remote -v # list the web address of the repository
- git rev-list @ -- file_name # list commit message of that particular file
- and No. of git commits that touched the file
- for file in *.pdf; do echo -n "$file "; git rev-list @ -- $file | wc -l; done
- git pull origin main # to update the repository
- git reflog # manage reflog information
- git diff hash1 hash2 # display difference between hash1 and hash2
- git status # to check the status of the remote repository
- git rm <filename> # delete/remove filename
- git pull origin main --allow-unrelated-histories
- # Delete the repository in Github
- https://help.github.com/en/github/administering-a-repository/deleting-a-repository
- # change git remote url
- git remote set-url <remote_name> <remote_url>
- git remote set-url origin https://git-repo/new-repository.git
- git remote set-url origin git@github.com:user/repository.git
- # remove files from a git repository
- To remove a file both from the Git repository and the filesystem, you can use
- git rm without any parameters (except for the file's name, of course):
- $ git rm <filename>
- If you only want to remove the file from the repository, but keep it on the
- filesystem, you can add the --cached flag:
- $ git rm <filename> --cached
- When trying to delete multiple files in a directory or via a glob pattern, you
- might want to perform a "dry-run" first and see which files would be removed:
- $ git rm <directoryname>/* --dry-run
- rm '<directoryname>/about.txt'
- rm '<directoryname>/general.txt'
- # remove directory from a git repository
- $ git rm -r directory/
- $ git commit -m 'remove directory'
- $ git push origin main
- # Commonly used git commands:
- add Add file contents to the index
- bisect Find the change that introduced a bug by binary search
- branch List, create, or delete branches
- checkout Checkout and switch to a branch
- clone Clone a repository into a new directory
- commit Record changes to the repository
- diff Show changes between commits, the commit and working trees, etc.
- fetch Download objects and refs from another repository
- grep Print lines matching a pattern
- init Create an empty git repository or reinitialize an existing one
- log Show commit logs
- merge Join two or more development histories
- mv Move or rename a file, a directory, or a symlink
- pull Fetch from and merge with another repository or a local branch
- push Update remote refs along with associated objects
- rebase Forward-port local commits to the updated upstream head
- reset Reset current HEAD to the specified state
- rm Remove files from the working tree and from the index
- show Show various types of objects
- status Show the working tree status
- tag Create, list, delete, or verify a tag object signed with GPG
- # Practical git commands:
- 1. Configure User Profile
- $ git config user.name "USERNAME"
- $ git config user.email "user@example.com"
- Add the --global option to set these policies globally.
- $ git config --global user.name "USERNAME"
- $ git config --global user.email "user@example.com"
- 2. Initialize Git Repositories
- $ git init
- 3. Add Project Files
- $ git add <file>
- $ git add *.php
- 4. Verify Added Files
- $ git status
- 5. Commit Changes to Repository
- $ git commit # invoke default Linux editor
- $ git commit -m "commit message"
- 6. Display the Logs
- $ git log # generalized information
- $ git log <filename> # specific file information
- 7. Verify Project Branches
- $ git branch # the output will mark the current branch with an asterisk
- 8. Reset Project Branches
- $ git reset
- $ git reset --soft
- $ git reset --hard
- 9. Add a New Branch
- $ git branch experimental # create a branch named experimental
- 10. Switch between Branches
- $ git checkout experimental
- 11. Delete a Project Branch
- $ git checkout main # switch to main branch
- $ git branch -D experimental # delete experimental branch
- 12. Check Differences among Commits, Trees, and Files
- $ git diff
- $ git diff experimental main
- 13. Merge Two Branches
- $ git merge experimental2 experimental1
- $ git merge -s ours experimental # merges experimental branch to current development branch
- $ git merge --no-commit experimental # merges branch experimental to current branch
- 14. Revert Existing Commits
- $ git revert <commit id> # revert changes introduced by <commit id>
- $ git revert HEAD~3 # relapses the fourth last commit in HEAD and performs a new commit
- 15. Stash Working Directory
- $ git stash
- $ git stash list
- 16. Clone a Repository
- $ git clone git://example.com/git.git
- $ git clone git://example.com/git.git/ test-dir/ # will download said project into test-dir/
- 17. Pull New Updates
- $ git pull
- 18. Push Your Updates
- $ git push
- 19. Display Remote Repositories
- $ git remote
- $ git remote --verbose
- 20. Connect to Remote Repositories
- $ git remote add origin <server> # add 'origin' as the remote name to the server
- 21. Add Tags to Your Project
- $ git tag 1.0.0 <commit id>
- $ git log
- $ git push origin --tags
- 22. Fetch Remote Data
- $ git fetch origin
- 23. Restore Non-Committed Changes
- $ git restore --staged test.php
- $ git restore --source=HEAD --staged --worktree test.php
- 24. Remove Files
- $ git rm *.php
- $ git rm -r dir/
- $ git rm --cached *.php # remove file from repository, not on the filesystem
- 25. Move or Rename Files
- $ git mv test.py newtest.py
- $ mv test.py newtest.py
- $ git add newtest.py
- $ rm test.py
- 26. Clean Untracked Files
- $ git clean
- $ git clean -n # options -f, -i, -n
- 27. Optimize Local Repositories
- $ git gc
- 28. Archive Local Repositories
- $ git archive --output=test
- 29. Search for Patterns
- $ git grep -iw 'import' main
- $ git grep 'import' $(git rev-list --all)
- 30. Manage Working Trees
- $ git worktree list
- $ git worktree add new-branch
- $ git worktree remove new-branch
- $ git worktree prune
- 31. Prune Untracked Objects
- $ git prune --dry-run
- $ git prune --verbose --progress
- 32. Pack Unpacked Objects
- $ git repack
- 33. List Unpacked Objects
- $ git count-objects
- 34. Validate the Object Database
- $ git fsck
- 35. Display Changes for Each Commit
- $ git whatchanged
- 36. Summarize Log Information
- $ git shortlog
- $ git shortlog --email --summary
- 37. Manage Cnfiguration Options
- $ git config --list
- $ git config --help
- 38. Consult Git Help
- $ git help
- $ git --help
- $ git <command> --help
- $ git commit --help
- 39. Consult Manual Page
- $ man git
- $ man git commit
- 40. Display Version Information
- $ git --version
- # To remove remote:
- git remote remove origin
- # Instead of removing and re-adding:
- git remote set-url origin git://new.url
- # To remove files from staging area:(to reverse git add <filename>)
- git reset <filename>
- git reset # reset all the files from the staging area
- # To list all deleted files
- git log --diff-filter=D --summary
- git log --diff-filter=D --summary | grep delete
- # Git commands that can help resolve merge conflicts
- ## General tools:
- git status % The status command is in frequent use when a working with Git and
- during a merge it will help identify conflicted files.
- git log --merge % Passing the --merge argument to the git log command will produce a
- log with a list of commits that conflict between the merging branches.
- git diff % diff helps find differences between states of a repository/files.
- This is useful in predicting and preventing merge conflicts.
- ## Tools for when git fails to start a merge
- git checkout % checkout can be used for undoing changes to files,
- or for changing branches
- git reset --mixed % reset can be used to undo changes to the working directory
- and staging
- ## Tools for when git conflicts arise during a merge
- git merge --abort % Executing git merge with the --abort option will exit from the
- merge process and return the branch to the state before the merge
- began.
- git reset % Git reset can be used during a merge conflict to reset conflicted
- files to a know good state
- # gitlab reference
- https://gitlab.com/pages/plain-html
- https://about.gitlab.com/stages-devops-lifecycle/pages/
- https://about.gitlab.com/blog/2016/04/07/gitlab-pages-setup/
- https://gitlab.com/html-themes/
- https://www.atlassian.com/git/tutorials/
- # downloading raw file
- https://github.com/<username>/<repo-name>/<some-directory>/<filename> # github page link
- wget https://raw.github.com/<username>/<repo-name>/<branch-name>/<some-directory>/<filename>
- curl -OL https://raw.githubusercontent.com/<username>/<repo-name>/<branch-name>/path/to/file
- O means that curl downloads the content
- L means that curl follows the redirection
- # fatal: refusing to merge unrelated histories
- git pull origin main --allow-unrelated-histories
- # 7 Git tricks
- 1. Autocorrection in Git (enable git autocorrection in git configuration)
- $ git config --global help.autocorrect 1
- If you want this to apply only to your current repository, omit the --global option.
- 2. Count your commits
- $ git rev-list --count <branch_name>
- 3. Optimize your repo
- $ git gc --prune=now --aggressive
- This command is an internal utility that cleans up unreachable or orphaned git
- objects in your repository.
- 4. Take a backup of untracked files
- Git, along with some Bash command piping, makes it easy to create a zip archive
- for your untracked files.
- $ git ls-files --others --exclude-standard -z | xargs -0 tar rvf ~/backup_untracked.zip
- The above command makes an archive (and exclude files listed in .gitignore).
- 5. Know your .git folder
- Current state of HEAD:
- $ cat .git/HEAD
- Description of your repository:
- $ cat .git/description
- 6. View a file of another branch
- Suppose you have a file called README.md, and it's in the "main" branch. You're
- working on a branch called "dev". With the following git command, you can do it
- from the terminal.
- $ git show main:README.md
- 7. Search in Git
- $ git rev-list --all | xargs git grep -F ' '
- $ git rev-list --all | xargs git grep -F 'font-size: 52 px;'
- # ssh-key setup (~/.ssh/)
- ssh-keygen -t ed25519 -C "gitlab"
- xclip -i -selection clipboard < id_gitlab.pub
- ssh -T git@gitlab.com
- eval $(ssh-agent -s)
- ssh-add /home/saran/.ssh/id_gitlab
- ssh -T git@gitlab.com
- Ref: https://docs.gitlab.com/ee/ssh/#working-with-non-default-ssh-key-pair-paths
- ssh-keygen -t ed25519 -C "github"
- xclip -i -selection clipboard < id_github.pub
- ssh -T git@github.com
- eval $(ssh-agent -s)
- ssh-add /home/saran/.ssh/id_github
- ssh -T git@github.com
- Ref: https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/
- generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
- ssh-keygen -t ed25519 -C "bitbucket"
- xclip -i -selection clipboard < id_bitbucket.pub
- ssh -T git@bitbucket.org
- eval $(ssh-agent -s)
- ssh-add /home/saran/.ssh/id_bitbucket
- ssh -T git@bitbucket.org
- ssh-keygen -t ed25519 -C "notabug"
- xclip -i -selection clipboard < id_notabug.pub
- ssh -T git@notabug.org
- eval $(ssh-agent -s)
- ssh-add /home/saran/.ssh/id_notabug
- ssh -T git@notabug.org
- ssh-keygen -t ed25519 -C "codeberg"
- xclip -i -selection clipboard < id_codeberg.pub
- ssh -T git@codeberg.org
- eval $(ssh-agent -s)
- ssh-add /home/saran/.ssh/id_codeberg
- ssh -T git@codeberg.org
- # conflicting changes in git
- 1. Cleaning up the working copy:
- Make sure the working copy doesn't contain conflicting changes. There are
- two ways to achieve this.
- a) saving local changes on a stash
- To preserve the local changes, can safely store them on a stash and
- available in case want them back at a later point.
- $ git stash --include-untracked
- b) discarding local changes
- If sure that don't need them anymore, can discard local changes completely.
- $ git reset --hard
- If untracked/new files, will have to use the "git clean" command to get rid
- of these.
- $ git clean -fd
- 2. Pull again
- After cleaned up any local changes/untracked files that would have been
- overwritten, the pull will finally work.
- $ git pull
- # rename a local git branch
- git branch -m old-name new-name # rename a local branch from another branch
- git branch -a # list all -- both local and remote -- branches to verify that it has been renamed
- # rename a remote git branch
- 1. rename a local branch by following the previous step
- 2. then delete the old branch and push the new one
- git push origin --delete old-name
- git push origin :old-name new-name
- 3. reset the upstream branch for new local branch
- git push origin -u new-name
- Ref: https://www.hostinger.com/tutorials/how-to-rename-a-git-branch/
- # modify commit message
- git commit --amend -m 'new commit message'
- # safe way to rollback to a previous state
- To revert everything from the HEAD back to the commit hash, meaning it will recreate
- that commit state in the working tree as if every commit after 0766c053 had been
- walked back.
- git revert --no-commit 0766c053..HEAD
- git commit -m '<commit message>'
- The --no-commit flag lets git revert all the commits at once, otherwise you'll be
- prompted for a message for each commit in the range, littering your history with
- unnecessary new commits.
- If want to have individual commits (instead of reverting everything with one big
- commit), then you can pass --no-edit instead of --no-commit, so that you don't have
- to edit a commit message for each reversion.
- git revert --no-edit 0766c053..HEAD
- # to view what haven't git added yet
- git diff file.txt
- # to view already added changes
- git diff --cached file.txt
- git diff --staged file.txt
- # force git pull to overwrite local files
- No need to fetch all remotes and branches if you're going to reset to the origin/main
- branch. So, instead of doing:
- git fetch --all
- git reset --hard origin/main
- I'd advise doing the following:
- git fetch origin main
- git reset --hard origin/main
- # add & commit and file
- (works only for already tracked files but not for untracked files)
- git commit -am 'commit message'
- # add subject and description to a commit message
- git commit -m 'subject' -m 'description ...'
- # fine grained control files to skip with .gitignore
- ignore all .a files: *.a
- but do track lib.a, even though you're ignoring .a files above: !lib.a
- only ignore the TODO file in the current directory, not subdir/TODO: /TODO
- ignore all files in any directory named "build": build/
- ignore doc/notes.txt, but not doc/server/arch.txt: doc/*.txt
- ignore all .pdf files in the doc/ directory and any of its subdirectories: doc/**/*.pdf
- # git rename a file/directory and retain the history
- Execute the following commands where the project .git/ directory present and also make
- sure all the changes are commited.
- Example:
- nmsc/Scripts/Python/Euler/
- then cd nmsc/
- ls
- .git/ Scripts/
- 1. rename innermost directory path
- from Scripts/Python/Euler/ to Scripts/Python/eulerscheme/
- git filter-repo --path-rename Scripts/Python/Euler/:Scripts/Python/eulerscheme/ --force
- 2. then rename previous innermost directory path
- from Scripts/Python/ to Scripts/python/
- git filter-repo --path-rename Scripts/Python/:Scripts/python/ --force
- 3. finally rename the outermost directory path from Scripts/ to scripts/
- git filter-repo --path-rename Scripts/:scripts/ --force
- then, 'git pull --rebase origin <branch>' before 'git push origin <branch>'
- # git pull merge/rebase/fast-forward
- hint: You have divergent branches and need to specify how to reconcile them.
- hint: You can do so by running one of the following commands sometime before
- hint: your next pull:
- hint:
- hint: git config pull.rebase false # merge
- hint: git config pull.rebase true # rebase
- hint: git config pull.ff only # fast-forward only
- hint:
- hint: You can replace "git config" with "git config --global" to set a default
- hint: preference for all repositories. You can also pass --rebase, --no-rebase,
- hint: or --ff-only on the command line to override the configured default per
- hint: invocation.
- # add all modified files
- git add -u
- # git bare directory (to maintain dotfiles)
- git init --bare # initialize bare git repository
- git init --bare $HOME/.dotfiles
- echo "alias config='/usr/bin/git --git-dir=$HOME/.dotfiles --work-tree=$HOME'" >> $HOME/.bashrc
- config config --local status.showUntrackedFiles no
- $ cd $HOME
- $ config add .bashrc
- $ config commit -m 'add bash configuration file'
- $ config push
- # using git restore to undo git add
- Undoing a git add can done simply by the git restore --staged command on the
- attected file:
- $ git restore --staged file.txt
- This will remove the file from Git's staging area, making sure it is not part of
- the next commit.
- If, at the same time, you also want to discard any local changes in this file,
- you can simply omit the --staged flag:
- $ git restore file.txt
- This will undo any modifications in this file since you last committed it.
- Please be careful with this command: undoing uncommitted local changes cannot be
- undone!
- Ref: https://www.git-tower.com/learn/git/faq/undo-git-add
- # combine git repositories with unrelated histories
- To merge repositoryA into repositoryB:
- $ cd path/to/repositoryB
- $ git remote add repositoryA /path/to/repositoryA
- $ git fetch repositoryA --tags
- $ git merge --allow-unrelated-histories repositoryA/main
- $ git remote remove repositoryA
- In case you want to put repositoryA into a subdirectory, you can use
- git-filter-repo (filter-branch is discouraged). Run the following commands
- before the commands above:
- $ cd path/to/repositoryA
- $ git filter-repo --force --to-subdirectory-filter repositoryA
- Note: In above command only commited files are taken, the uncommited files are
- not taken even if it present in the repositoryA. A seperate directory with
- repositoryA is created within the existing repositoryA directory.
- Example:
- To merge julia/ into a subdirectory in codelearn/:
- $ cd ~/julia/
- $ git filter-repo --force --to-subdirectory-filter julia
- $ cd ~/codelearn/
- $ git remote add julia ~/julia
- $ git fetch julia --tags
- $ git merge --allow-unrelated-histories julia/main
- $ git remote remove julia
- Reference:
- stackoverflow.com/questions/1425892/how-do-you-merge-two-git-repositories
- https://jeffkreeftmeijer.com/git-combine/
- # create commit with different date
- $ GIT_AUTHOR_DATE='Mon May 18 19:32:10 2020 +0530' \
- GIT_COMMITTER_DATE='Mon May 18 19:32:10 2020 +0530' \
- git commit -m 'Commit message'
- # add multi-line git commit messages
- $ git commit program.c -m "Note the Changes" -m "- Fixed a bug"
- # rename the master branch to main
- renaming the local master branch to main:
- The first step is to rename the "master" branch in your local git repositories
- $ git branch -m master main
- Let's quickly check if this has worked as expected
- $ git status
- On branch main
- Your branch is up to date with 'origin/master'.
- nothing to commit, working tree clean
- renaming the remote master branch as well:
- Make sure your current local HEAD branch is still "main" when executing the
- following command
- $ git push -u origin main
- We now have a new branch on the remote named "main". Let's go on and remove the
- old "master" branch on the remote
- $ git push origin --delete master
- [Reference: https://www.git-tower.com/learn/git/faq/git-rename-master-to-main/]
- # create a pull request
- When you want to work on a GitHub project (https://github.com/rrthomas/pdfjam.git),
- the first step is to fork a repo. This creates a new copy of pdfjam repo under your
- GitHub user account with a URL like:
- https://github.com/dsarvan/pdfjam
- The copy includes all the code, branches, and commits from the original repo. Next
- clone the repo by opening the terminal and running the command:
- git clone https://github.com/dsarvan/pdfjam
- Once the repo is cloned, you need to do two things:
- 1. Create a new branch by issuing the command:
- git checkout -b refactor/pdfjam
- 2. Create a new remote for the upstream repo with the command:
- git remote add upstream https://github.com/rrthomas/pdfjam
- In this case, upstream repo refers to the original repo you created your fork from.
- Now you can make changes to the code. The following code push it to refactor/pdfjam
- branch.
- git push -u origin refactor/pdfjam
- Once you push the changes to your repo, the 'Compare & pull request' button will
- appear in rrthomas/pdfjam Github page. Click it and you'll be taken to 'Open a
- pull request'. Open a pull request by clicking the 'Create pull request' button.
- This allows the repo's maintainers to review your contribution. From here, they
- can merge it if it is good, or they may ask you to make some changes.
- Reference: https://opensource.com/article/19/7/create-pull-request-github
- # git branch naming practices
- Prefixing your branch names with a type helps categorize branches and provides
- additional context to everyone working on the project. Some commonly used types
- include bugfix/, develop/, feature/, hotfix/, main/, refactor/, release/.
- * develop/ is the branch you'll be doing most of your work off of; it's also
- the branch that represents the code to be deployed in the next release.
- * feature/ branches represent non-trivial features and fixes that have not yet
- been deployed (a completed feature/ branch is merged back into develop/).
- * updating main/ is done through the creation of a release/.
- * main/ is always 'production ready' code. Commits are never made directly to
- main/. Rather, code on main/ only gets there after a production release/
- branch is created and finished. Thus the code on main/ is always able to be
- released to production. Also, main/ is always in a predictable state, so you
- never need to worry if main/ (and thus production) has changes one of your
- other branches doesn't.
- * develop/ branch is where most of your work is done. This branch contains all
- of the completed features and bug fixes yet to be released; nightly builds or
- continuous integration servers should target develop, as it represents the
- code that will be included in the next release. For one-off commits, feel free
- to commit to develop/ directly.
- * for larger features, a feature/ branch should be created. feature/ branches
- are created off of develop/. They can be small enhancements for the next
- release or further out changes that, nonetheless, need to be worked on now. To
- start work on a new feature, use:
- $ git flow feature start <feature name>
- This creates a new branch, feature/<feature name>. Commits are then made to
- this branch as normal. When the feature is complete and ready to be released
- to production, it should be merged back into develop/ using the following
- command:
- $ git flow feature finish <feature name>
- This merges the code into develop/ and deletes the feature/<feature name>
- branch.
- * release/ branch is created from develop/ when you're ready to begin a
- production release. Create one using the following command:
- $ git flow release start <release number>
- Note that this is the first time a version number for the release is created.
- All completed and ready to be released features must already be on develop/
- (and thus feature finished). After your release branch is created, release
- your code. Any small bug fixes needed after the release are made directly to
- the release/<release number> branch. Once it has settled down and no more bug
- fixes seem necessary, run the following command:
- $ git flow release finish <release number>
- This merges your release/<release number> changes back into both main/ and
- develop/, meaning you never need to worry about either of those branches
- lacking changes that are in production (perhaps as the result of a quick bug
- fix).
- * while potentially useful, hotfix/ branches are, I would guess, little used in
- the real world. hotfix/ is like a feature/ branch off of main/: if you've
- already closed a release/ branch but realize there are vital changes that need
- to be released, create a hotfix/ branch off of main/ (at the tag created
- during $ git flow release finish <release number>) like so:
- $ git flow hotfix start <release number>
- After you make your changes and bump your version number, finalize the hotfix/
- via
- $ git flow hotfix finish <release number>
- This, like a release/ branch (since it essentially is a type of release
- branch), commits the changes to both main/ and develop/.
- The reason I assume they're rarely used is because there is already a
- mechanism for making changes to released code: committing to an un-finished
- release branch. Sure, in the beginning, teams may git flow release finish ...
- too early, only to find they need to make some quick changes the next day.
- Over time, though, they'll settle on a reasonable amount of time for a
- release/ branch to remain open and, thus, won't have a need for hotfix/
- branches. The only other time you would need a hotfix/ branch is if you needed
- a new 'feature' in production immediately, without picking up the changes
- already in develop/. That strikes me as something that happens (hopefully)
- very rarely.
- # git commit template
- A properly formed Git commit subject line should always be able to complete
- the following sentence:
- * If applied, this commit <will your subject line here>
- ** Example:
- [type](optional scope): [subject]
- [optional body]
- [optional footer]
- ** Type
- Must be one of the following:
- * build - Build related changes
- * chore - Build process or auxiliary tool changes
- * docs - Documentation only changes
- * feat - A new feature
- * fix - A bug fix
- * perf - A code change that improves performance
- * refactor - A code change that neither fixes a bug or adds a feature
- * revert - Reverting things
- * style - Markup, white-space, formatting, missing semi-colons...
- * test - Adding missing tests
- ** Subject
- The subject contains a succint description of the change:
- * Use the imperative, present tense: "change" not "changed" nor "changes"
- * No dot (.) at the end.
- ** Scope
- A scope may be provided to a commit’s type, to provide additional contextual
- information and is contained within parenthesis.
- e.g., feat(parser): add ability to parse arrays
- ** Body
- Just as in the subject, use the imperative, present tense: "change" not "changed"
- nor "changes".
- The body should include the motivation for the change and contrast this with previous
- behavior.
- ** Rules
- The 7 rules of a great commit message
- 1. Separate subject from body with a blank line
- 2. Limit the subject line to 50 characters
- 3. Summary in present tense. Not capitalized
- 4. Do not end the subject line with a period
- 5. Use the imperative mood in the subject line
- 6. Wrap the body at 72 characters
- 7. Use the body to explain what and why vs. how
- # merge develop branch into main
- To merge develop branch into the main branch - you checkout main and merge develop:
- $ git checkout develop
- # ...develop some code...
- $ git add .
- $ git commit -m 'some commit message'
- $ git checkout main
- # ...switched to branch main...
- $ git merge develop
- Reference: https://stackabuse.com/git-merge-branch-into-master/
- # undo latest local commit
- Let's create a file we'd like to add to our repository, add it and finally commit:
- $ echo "Hello World!" >> file.txt
- $ git add file.txt
- $ git commit -m 'added file.txt'
- $ echo "It's a great day today :(" >> file.txt
- $ git add file.txt
- $ git commit -m 'modified file.txt'
- Yikes, we've accidentally left in a horrible typo in the content. We've put in
- the parentheses in the wrong way! And we've just committed that mistake:
- $ git log --pretty=oneline
- df9fc1b773ecf3ba14c990615831f1087817611f (HEAD -> main) Modified file.txt
- 55db4f399d1ad64e0a40e1858d23fef0ffe31fb0 Added file.txt
- To remove a local commit, assuming it hasn't been pushed to the remote repository yet,
- we can use the `git reset` command, which is effectively the opposite of `git add`:
- $ git reset HEAD~
- Unstaged changes after reset:
- M file.txt
- We've reset the HEAD (pointer to the last commit), pointing it back (~) to the
- previous commit. By including a number after the tilde, we could've gone back
- multiple commits instead of just one.
- Once reset, the change we've made to the file.txt, i.e. the erroneous modification is
- unstaged. Let's take a look at the log again:
- $ git log --pretty=oneline
- 55db4f399d1ad64e0a40e1858d23fef0ffe31fb0 (HEAD -> main) Added file.txt
- And the status is:
- $ git status
- On branch main
- Changes not staged for commit:
- (use "git add <file>..." to update what will be committed)
- (use "git restore <file>..." to discard changes in working directory)
- modified: file.txt
- no changes added to commit (use "git add" and/or "git commit -a")
- However, what are the contents of the file now?
- $ nano file.txt
- Hello World
- It's a great day today :(
- By default, the reset command is --soft. The --soft flag doesn't reset the changes
- done to the file, just removes the commit that was made. Let's go ahead and re-commit
- this mistake again, so we can take a look at what happens when we run the --hard
- option.
- Hard Reset:
- Instead of the --soft reset, which we can use to simply undo the commit, while leaving
- the files intact (and the changes still present, which is why the git status command
- prompted us with staging the changes) - we can also do a --hard reset:
- $ git reset --hard HEAD~
- HEAD is now at 55db4f3 Added file.txt
- This time around, the changes aren't unstaged, like before. They're removed. If we
- check the log, it'll look much like last time:
- $ git log --pretty=oneline
- 55db4f399d1ad64e0a40e1858d23fef0ffe31fb0 (HEAD -> main) Added file.txt
- Though, if we check the status:
- $ git status
- On branch main
- nothing to commit, working tree clean
- There's nothing to commit, because the change that was made to the file in the
- previous commit was also removed, setting the HEAD back to the first commit:
- $ nano file.txt
- Hello World!
- Reference: https://stackabuse.com/git-undo-latest-local-commit/
- # adding multi-line commit messages
- $ git commit index.js -m "My Changes" -m "- Fixed a critical bug" -m "- Probably
- added more bugs"
- These multiple messages will then look like this in the resulting commit:
- My Changes
- - Fixed a critical bug
- - Probably added more bugs
- Another option, which depends on the shell you're using, is to just enter a single or
- double quote and press Enter, without closing the quote. This works well in Bash,
- which doesn't enter the command until you've closed the quote:
- $ git commit index.js -m "My Changes
- - Fixed a critical bug
- - Probably added more bugs
- "
- And finally, you don't actually need to use the -m flag at all. If you omit this flag
- then Git will automatically open a text editor for you to enter the commit message.
|