Git is a distributed version control system, popular for keeping code repositories in sync.
git pull
git status
git add .
git commit -m "commit message"
git push
You can also create aliases in your .bashrc
file
alias gcu='git commit -m "Update notes"; git push'
- Use the imperative mood in the subject line
- Capitalize the subject line
- Do not end the subject line with a period
- Limit the subject line to 50 characters
- Separate subject from body with a blank line
- Wrap the body at 72 characters
- Use the body to explain what and why vs. how
- Capitalize the subject line
Source: http://chris.beams.io/posts/git-commit/#seven-rules
https://gist.github.com/julienbourdeau/e605e4b8b47da97c249a0f72598529c8
git config --list
git config --global init.defaultBranch main
If you want to see - what repo something pushes back to - the configured id for a given local repo
Use
git config --list --show-origin
To see what the remote server is set to, use:
git remote -v
Sources that a repository is set up to track or follow.
The origin
is the one that the repo will push to / pull from by default.
It is possible to have more than one remote !
Remotes can be called whatever you want.
upstream
can be useful for tracking a boilerplate source for a project.
git remote add upstream [email protected]:project/boilerplate.git
git remote -v
https://unfoxnews.com/keep-track-of-multiple-git-remote-repositories/
Sometimes projects get checked out using the public url, but then changes are made.
git remote remove origin
git remote add origin [email protected]:charlesbrandt/public.git
git push --set-upstream origin main
git branch --set-upstream-to=origin/main main
git pull
*** Please tell me who you are.
Run
git config user.email "[email protected]"
git config user.name "Your Name"
to set the identity to use when making changes to the current repository. Different repositories may have different accounts associated with them.
If that's not something your work requires, you can also set a single account globally:
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
On a remote shared sever, it may not be appropriate to set user credentials at the account level. In this case, it is possible to provide your details as part of the commit:
git commit --author="Your Name <[email protected]>"
If you end up committing as a system user and need to update the last commit message, you can use:
git commit --amend --author="Your Name <[email protected]>"
use ssh -A
to share your local credentials with the machine you connect to.
Then if you register your local machine's public ssh key with a service like Gitlab or Github, you won't have to type your username and password every time you push or pull.
If you think you want to store your password, consider setting up an ssh key with your git server instead.
(Don't do this) to store passwords:
git config --global credential.helper store
These credentials are stored in plaintext. Plaintext is insecure, especially on shared systems. via
https://git-scm.com/docs/gitcredentials
$ git config --global credential.helper cache
# Set git to use the credential memory cache
$ git config --global credential.helper 'cache --timeout=3600'
# Set the cache to timeout after one hour (setting is in seconds)
git init
The default branch on git init
is currently set to master.
If you want to change it to main
, this is a good point to do so.
git checkout -b main
git branch -d master
git branch -a
Confirm the remote server is set to your own repo:
git remote -v
From here you can add different remotes (origins and upstreams) as needed.
(See also server section)
To see the changes to the repository in reverse chronological order:
git log
To see history for a specific file:
git log --follow -p -- file
To see who has made commits to a repository.
git blame filename
see also:
git bisect
https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History
Tracking a move with git with:
git mv [src] [destination]
** Important Note **
This may affect the ability to see history of files via log
.
currently (2020.12), GitHub is not able to associate the history of a moved file with it's previous location's history:
https://github.community/t/renaming-folder-within-a-repo-loses-file-history/1752
If you try to pull in changes to a file you've modified locally, Git does not try to do the merge.
Use stash to move local changes to the side while pulling in changes from remote.
git stash
Then to unstash:
git stash pop
https://www.atlassian.com/git/tutorials/saving-changes/git-stash https://dev.to/alediaferia/git-tips-for-trunk-based-development-1i1g
Newer versions of git show reminders about these commands when running git status
git reset
https://stackoverflow.com/questions/348170/how-do-i-undo-git-add-before-commit
git checkout path/to/file
will revert the local changes to path/to/file
If the commit has not been pushed publicly (local only), it's easy:
git reset HEAD~1 --soft
https://stackoverflow.com/questions/19859486/how-to-un-commit-last-un-pushed-git-commit-without-losing-the-changes
How to un-commit last un-pushed git commit without losing the changes - Stack Overflow
git commit -m "Commit title
Commit body
Co-authored-by: First Person <[email protected]>
Co-authored-by:
"
Ideally, do this before pushing up to a public repo, otherwise it results in a branch merge. This will change the most recent commit:
git commit --amend
https://docs.github.com/en/github/committing-changes-to-your-project/creating-and-editing-commits/changing-a-commit-message
Changing a commit message - GitHub Docs
A tag is a bit like a branch, but you don't need to check it out.
git tag -a v1.4 -m 'version 1.4'
git clone <url> --single-branch
via: https://stackoverflow.com/questions/1778088/how-do-i-clone-a-single-branch-in-git
git branch --show-current
git branch --all
git checkout name_of_branch
To create a local copy of the remote branch:
git checkout -b branch-name origin/feature/branch-name
Assumes you have already checked out the repository locally. Then:
git checkout -b upstream
Which is shorthand for:
git branch upstream
git checkout upstream
Once you merge a feature branch back in to main
, feel free to remove it. It's a good idea to keep your branch names somewhat clean.
git branch -d <local-branch>
If the branch has been shared publicly, and deleted on the remote repository, but still shows up locally (in the list of remote branches), it can be removed with
git remote prune origin
To preview this action, use
git remote prune origin --dry-run
If a new local branch has not been pushed up to the origin, use
git push origin [branch-name]
If you wish to set tracking information for this branch:
git branch --set-upstream-to=<remote>/<branch> main
Allows you to pull in changes from main / different branch.
Use merge if your branch is already pushed.
To merge changes
git merge origin/main
https://duckduckgo.com/?q=git+import+changes+on+master+to+branch&t=canonical&ia=web
git import changes on master to branch at DuckDuckGo
See also web-ui-api-db/README.md for a branching strategy on handling changes to a foundation that exists outside of the current repository.
git diff branch1..branch2
Tags are like branches that don't have separate revisions. I believe they can be turned in to branches later?
git tag <tagname>
Creates a local tag
git push origin --tags
to push the tag up to the origin.
https://stackoverflow.com/questions/18216991/create-a-tag-in-a-github-repository
git branch -m <oldname> <new_name>
If you want to rename the current branch
git branch -m <new_name>
If the current branch is available publicly, you'll need to rename it on the remote repo as well.
# Rename the local branch to the new name
git branch -m <old_name> <new_name>
# Delete the old branch on remote - where <remote> is, for example, origin
git push <remote> --delete <old_name>
# Or shorter way to delete remote branch
git push <remote> :<old_name>
git remote -v
# Push the new branch to remote
git push <remote> <new_name>
# e.g.
git push origin <new_name>
# Reset the upstream branch for the new_name local branch
git push <remote> -u <new_name>
via: https://stackoverflow.com/questions/6591213/how-do-i-rename-a-local-git-branch
Check out the repository, then
git branch -m master main
git checkout main
git push -u origin main
git push origin --delete master
This may require updating the HEAD reference on Github directly. For a locally hosted git repository, edit the HEAD
file on the server. Then, running the following should work:
git push origin --delete master
git branch -m master main
git push -u origin main
https://dev.to/afrodevgirl/replacing-master-with-main-in-github-2fjf
Be sure to update defaults in your git server host:
https://stackoverflow.com/questions/30987216/change-default-branch-in-gitlab
There are different ways to use branches.
https://guides.github.com/introduction/flow/
https://nvie.com/posts/a-successful-git-branching-model/
https://stackoverflow.com/questions/15072243/git-with-development-staging-and-production-branches
https://stackoverflow.com/questions/24582319/branching-and-merging-best-practices-in-git
When it's time to merge a feature branch to the main branch, a few steps are necessary. Examples include diffing the branches, merging the branches, and creating a pull request in your issue tracker to document the change. Frequently these step are done directly in a web service like Github. Better integration with issue tracker that way. Notification emails are automatically sent to collaborators. However, if you need to do it locally for some reason:
You can create the branch via a hash:
git branch branchname <sha1-of-commit>
Or by using a symbolic reference:
git branch branchname HEAD~3
https://stackoverflow.com/questions/2816715/branch-from-a-previous-commit-using-git
TODO: confirm
git pull
should do the trick
Similar to merge, but re-writes the history. Use rebase if your branch is local and hasn't been pushed to origin. However, generally, a merge is just fine!
Never rebase a public branch / master -- makes a mess for others who have it checked out already
git checkout name_of_branch
git rebase master
https://stackoverflow.com/questions/5340724/get-changes-from-master-into-branch-in-git version control - Get changes from master into branch in Git - Stack Overflow
https://www.atlassian.com/git/tutorials/merging-vs-rebasing Merging vs. Rebasing | Atlassian Git Tutorial
https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging
When working on a branch, git pull
will pull changes from the branch, but git push
has some surprising behavior that tries to push changes to all matching branches:
error: failed to push some refs to 'https://github.com/remote/repo'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. If you did not intend to push that branch, you may want to
hint: specify branches to push or set the 'push.default' configuration variable
hint: to 'simple', 'current' or 'upstream' to push only the current branch.
git config push.default simple # just for the current repository
git config --global push.default simple # globally for your account
https://longair.net/blog/2011/02/27/an-asymmetry-between-git-pull-and-git-push/
A fork is another term for a cloned copy of the repository.
https://stackoverflow.com/questions/3611256/forking-vs-branching-in-github
https://github.com/git-lfs/git-lfs/blob/main/INSTALLING.md
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs
Testing with:
git lfs install
Should always yield once installed:
Git LFS initialized.
Find the latest version:
https://git-lfs.com/ Git Large File Storage | Git Large File Storage (LFS) replaces large files such as audio samples, videos, datasets, and graphics with text pointers inside Git, while storing the file contents on a remote server like GitHub.com or GitHub Enterprise.
Download it
cd ~/Downloads
wget https://github.com/git-lfs/git-lfs/releases/download/v3.3.0/git-lfs-linux-amd64-v3.3.0.tar.gz
tar zxvf git-lfs-linux-amd64-v3.3.0.tar.gz
cd git-lfs-3.3.0/
sudo ./install.sh
Adapted from: https://duckduckgo.com/?t=ffab&q=git+lfs&ia=web git lfs at DuckDuckGo https://docs.github.com/en/repositories/working-with-files/managing-large-files/installing-git-large-file-storage Installing Git Large File Storage - GitHub Docs
Submodules are remote repositories that are tracked separately, but needed for the local project to work.
Submodles allow for external dependencies to be noted and included.
To get submodules on clone:
git clone --recurse-submodules -j8 git://github.com/foo/bar.git
cd bar
To pull in submodules for an already checked out repository:
git submodule update --init --recursive
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint: git submodule add <url> path/to/mod
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint: git rm --cached path/to/mod
hint:
hint: See "git help submodule" for more information.
git submodule add https://gitlab.com/charlesbrandt/public docs
https://git-scm.com/book/en/v2/Git-Tools-Submodules
To remove a submodule you need to:
Delete the relevant section from the .gitmodules file.
Stage the .gitmodules changes git add .gitmodules
Delete the relevant section from .git/config.
Run git rm --cached path_to_submodule (no trailing slash).
Run rm -rf .git/modules/path_to_submodule (no trailing slash).
Commit git commit -m "Removed submodule "
Delete the now untracked submodule files rm -rf path_to_submodule
https://gist.github.com/myusuf3/7f645819ded92bda6677
Typically a specific version of the submodule is tracked.
https://duckduckgo.com/?t=ffab&q=git+submodule+track+master&atb=v343-1&ia=web
git submodule track master at DuckDuckGo
https://stackoverflow.com/questions/9189575/git-submodule-tracking-latest
git submodule tracking latest - Stack Overflow
https://stackoverflow.com/questions/1777854/how-can-i-specify-a-branch-tag-when-adding-a-git-submodule/18799234#18799234
How can I specify a branch/tag when adding a Git submodule? - Stack Overflow
This is also the same scenario as working with an upstream or boilerplate.
If you want to merge project-a into project-b:
cd path/to/project-b
git remote add project-a path/to/project-a
git fetch project-a
git merge --allow-unrelated-histories project-a/master # or whichever branch you want to merge
git remote remove project-a
https://duckduckgo.com/?q=merge+separate+git+repositories&t=canonical&ia=qa merge separate git repositories at DuckDuckGo https://stackoverflow.com/questions/1425892/how-do-you-merge-two-git-repositories How do you merge two Git repositories? - Stack Overflow
Before merging, be sure your incoming repository is in it's new subdirectory, otherwise everything will be merged in at the root level.
cd ~/Downloads/technical mkdir technical
This fails with an error:
git mv * technical
Instead, use the -k option:
git mv -k * technical
git commit -m "moving all items to a sub-directory for easier merging"
cd /c/user
git remote add technical ~/Downloads/technical
git fetch technical
git merge --allow-unrelated-histories technical/master # or whichever branch you want to merge
Might have a merge message here, then:
git remote remove technical
If you need to undo a change from a previous commit, a revert
is generally preferred over a reset
. Resets can cause problems with other shared instances of the repository.
Reminder: It is possible to revert
a previous revert
to bring the code back in at a later date.
https://stackoverflow.com/questions/1616957/how-do-you-roll-back-reset-a-git-repository-to-a-particular-commit How do you roll back (reset) a Git repository to a particular commit? - Stack Overflow https://stackoverflow.com/questions/4114095/how-do-i-revert-a-git-repository-to-a-previous-commit git checkout - How do I revert a Git repository to a previous commit? - Stack Overflow https://duckduckgo.com/?q=vuetify+autocomplete+rules&t=canonical&ia=web git undo pull request merge at DuckDuckGo https://stackoverflow.com/questions/6481575/undo-a-merge-by-pull-request git - Undo a merge by pull request? - Stack Overflow https://stackoverflow.com/questions/34638188/how-to-undo-merge-of-master-branch git - How to undo merge of master branch? - Stack Overflow https://www.datree.io/resources/git-undo-merge "Git undo merge" - How to undo merge in git [Tutorial]
Ignore changes to a file
git update-index --assume-unchanged path/to/file
Resume tracking again:
git update-index --no-assume-unchanged path/to/file
https://stackoverflow.com/questions/13442130/git-temporarily-ignore-trivial-changes-to-files Git - Temporarily ignore trivial changes to files - Stack Overflow
Sometimes it's easier to use an interface like gitlab (run it locally) or github to browse the history of the commits to the project.
If you do not know the exact path you may use
git log --all --full-history -- **/thefile.*
If you know the path the file was at, you can do this:
git log --all --full-history -- <path-to-file>
An alternative:
git rev-list -n 1 HEAD -- <file_path>
This should show a list of commits in all branches which touched that file. Then, you can find the version of the file you want, and display it with...
git show <SHA> -- <path-to-file>
Or restore it into your working copy with:
git checkout <SHA>^ -- <path-to-file>
Note the caret symbol (^), which gets the checkout prior to the one identified, because at the moment of <SHA>
commit the file is deleted, we need to look at the previous commit to get the deleted file's contents
https://stackoverflow.com/questions/953481/find-and-restore-a-deleted-file-in-a-git-repository
If someone adds a directory with large binary files, it may be useful to remove that directory from the history to avoid having to download the large binary data with every clone
of the repo.
git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch chats/transcriptions/*'
WARNING: git-filter-branch has a glut of gotchas generating mangled history
rewrites. Hit Ctrl-C before proceeding to abort, then use an
alternative filtering tool such as 'git filter-repo'
(https://github.com/newren/git-filter-repo/) instead. See the
filter-branch manual page for more details; to squelch this warning,
set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...
git push origin master --force
Worked on 2024.04.08
https://stackoverflow.com/questions/2047465/how-do-i-delete-a-file-from-a-git-repository
This is an alternative way to do the same thing:
git filter-branch --tree-filter "rm -rf node_modules" --prune-empty HEAD
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git gc
echo node_modules/ >> .gitignore
git add .gitignore
git commit -m 'Removing node_modules from git history'
git push origin master --force
-- Remove the history from
rm -rf .git
-- recreate the repos from the current content only
git init
git add .
git commit -m "Initial commit"
-- push to the github remote repos ensuring you overwrite history
git remote add origin [email protected]:<YOUR ACCOUNT>/<YOUR REPOS>.git
git push -u --force origin main
via https://gist.github.com/stephenhardy/5470814
In Gitlab, you'll need to explicitly allow "Force push" in the project -> settings -> Repository -> Protected Branches. Set "Allowed to force push" to enabled. Once this action is complete, it's a good idea to set this back to disabled.
Knowing the command line interface is useful when you only have a terminal to work with (ssh, termux, etc).
However, there are plenty of cases where a full desktop environment is availabe. In that case, no need to limit yourself to the CLI.
VS Code has a lot of useful git utilities built in.
Github Desktop is a nice GUI client. Github Desktop is only available on Mac and Windows.
Clients available for linux are listed here:
https://git-scm.com/download/gui/linux
Looking at:
sudo pacman -Ss git-cola
# not found
sudo pacman -S gitg