Git notes
Table of Contents
- Git notes
- Help! GitHub keeps asking me for my username and password
- Help! I'm getting Permission denied (publickey)
- List how a file was last modified
- List current commit hash
- List all tags in repository
- List which files differ between branches
- Listing the files git cares about
- Listing when a file was first added to a repository
- List changes that would be done by pulling
- List branch topology
- Update remote to use ssh
- Undo a commit
- Undo a partial merge resolution
- Undo all unstaged changes (checkout all the files)
- Unstage all staged files
- Repository and file sizes
- Bringing fork up to date
- Bringing branch up to date
- Branches
- Visiting an old commit
- Magit via spacemacs
- Editor
- GitHub
- GitLab
Git notes
Help! GitHub keeps asking me for my username and password
Make sure that you have got your remote set to the correct location, it should look like the following:
origin git@github.com:aezarebski/foobar.git
If you have cloned a repository via HTTPS you will need to change this.
Help! I'm getting Permission denied (publickey)
This has happened when for some strange reason SSH has failed to recognise the correct set of keys. The fix was to use the following command to add the keys that were there but weren't being used.
ssh-add ~/.ssh/<your private key>
To help with debugging this issue, you can attempt to connect via SSH with all the debugging messages printed. In particular, pay attention to the names of the keys being tried.
ssh -vvvv git@gitlab.com
Note that you may need to use some extra commands to restart the ssh agent
eval "$(ssh-agent -s)" kill -9 <agent pid> eval `ssh-agent` ssh-add ~/.ssh/<your private key> ssh git@gitprovider.com
List how a file was last modified
To see a list of the last commit relevant to each line of a file use the following:
git blame <file>
If you want to limit this to modifications to lines \(n\) through to \(m\) then
git blame -L <n>,<m> <file>
You can also use git log -L <n>,<m>:<file>
to get a log of all the
commits that have changed those lines of the file.
List current commit hash
git log -1 --format="%H"
List all tags in repository
git tag
Run git tag --help
to get more details about this, in particular, the -l
flag might be useful to refine the list by giving a pattern to match against.
For example, git tag -l 'v2.6*'
to get a list of the tags starting with
v2.6
.
List which files differ between branches
git diff <branch> --name-only
Listing the files git cares about
git ls-files
Listing when a file was first added to a repository
git log --diff-filter=A -- <path/to/file>
List changes that would be done by pulling
The dry run form of fetch will list the changes that would be made by git pull
but does not actually make any changes to the code.
git fetch --dry-run
It seems that git pull
is the same as git fetch
followed by git merge
so
using git fetch
should provide a way to preview what changes would be made by
git pull
.
List branch topology
Stackoverflow has this answer
git log --graph --decorate --oneline
Update remote to use ssh
To find where the current remote is there is the following command
git remote -v
Once you have registered your keys with the remote, you can update the repository settings with the following.
git remote set-url origin git@(github.com|bitbucket.org):azarebski/<repositoryname>.git
Undo a commit
There is an amend
function for modifying an existing commit. If you want to
completely undo the last commit though, issue the following command
git reset --hard HEAD~1
Or if you want to go back to a particular commit, issue the following command
git reset --hard <commit-sha>
The --hard
part is so that the changes made are removed, if you wanted to keep
the changes it would be --soft
.
Undo a partial merge resolution
If you started to resolve a merge conflict and then want to undo the hunks you have resolved, the following command will help
git checkout -m <file>
Undo all unstaged changes (checkout all the files)
If you want to undo all the changes you have made to the files in the repository you can use the following command. Warning this will remove all changes to the files in the repository, so double-check there are no changes you want to keep first.
git checkout .
Unstage all staged files
git reset
Repository and file sizes
GitHub recommends that repositories are kept below 1GB and that individual files are all kept below 100MB. There are ways around this, but this sensible to keep things running smoothly.
Bringing fork up to date
git remote add upstream <URL> git fetch upstream git merge upstream/master master
Keep in mind that this only brings your local repository up to date, you still need to push this if you want the other clones to be up to date. Also, this can be a slow process if your fork is a long way behind, so it might be wise to do this regularly.
Bringing branch up to date
Suppose you want to bring edits on main
into your development branch, dev
.
git checkout dev git merge master --no-ff
Branches
Finalising a merge
The tool meld
is a GUI which greatly simplifies the task of refining what code
to take from which branch. Suppose you are on branch X
and you want to pull
some stuff over from branch Y
. Check out branch X
and run the following
git difftool Y
This will ask you if you want to use meld to resolve difference for the files
with differences. You can install meld
with your package manager on linux.
If you only want to consider a subset of files when using this, you can add a path argument to the end of the command to restrict it to just files matching that path.
Query
The following shows a visualisation of the commits among all the branches.
git log --all --decorate --oneline --graph
To get a list of the filenames of the files that differ between commits use the following
git diff --name-only SHA1 SHA2
You can also get a list of just the names of the files that differ between your current branching with the following command.
git diff <otherBranchName> --name-only
Cautious merging
You can merge a branch without committing the results and squashing the commits in the branch with the following
git merge --squash --no-commit <branch>
Squashing commits
Suppose you have a master
branch and a feature-messy
branch. The
feature-messy
branch has a bunch of messy commits. The following steps allow
you to include all the work from feature-messy
into a single commit in a new
branch, feature-neat
, which can then be merged into master without looking
messy.
git checkout master git checkout -b feature-neat git checkout feature-neat git merge --squash feature-messy git commit # This step may require more attention git checkout master git merge feature-neat
Updating a feature branch
Suppose after working on feature-branch
for a while you want to bring it up to
date with changes that have happened on master
. The following is taken for a
gist explaining how to do just that!
git checkout master git fetch -p origin git merge origin/master git checkout <feature-branch> git merge master git push origin <feature-branch>
Checking out edits to single files
Suppose you are on branch X
and there are edits to files f1
and f2
that
you want from branch Y
. To pull those edits over you can do the following.
git checkout X # we need to be on X git checkout Y f1 f2 # checkout out the edited files git commit -m "Pull edits over" # Profit!
Visiting an old commit
To check what something looked like in an old commit, find the commit hash and
use git checkout <hash>
. Once you are finished looking around go back to the
branch you're working on with git checkout <branch>
.
Magit allows you to look at the list of commits, get a preview of the edit made in that commit and then check out the revision from the log menu.
Magit via spacemacs
I have some notes on the magit git client too!
Editor
The following command should set vim as the default editor on a machine.
git config --global core.editor "vim"
GitHub
Issue tracker
Feature request template
# Description A couple of sentences explaining the problem the feature helps solve... Please be clear what is considered in-scope and out-of-scope. # (Optional) Suggested solution - Details of the technical implementation - Tradeoffs made in design decisions - Caveats and considerations for the future If there are multiple solutions, please present each one separately. Save comparisons for the very end. ## Alternatives If you have alternatives that you have already found insufficient, please mention them here.
Bug report template
# Description Here are a couple of sentences explaining the problem... # Files involved - `foo.sh` - `bar.py` # To reproduce 1. Do this thing. 2. Do that thing. 3. Observe problem # Tasks 1. Confirm problem. 2. Solve problem. 3. Profit!
ssh keys
The following is copied from this stackoverflow answer. To generate some keys do the following:
cd ~/.ssh
ssh-keygen
then go to the Settings in GitHub/GitLab and copy the public key github account. Finally run
ssh -T git@github.com
and GitHub should respond with a message saying that you're all set to go. If this does not work, it might help to restart the ssh agent as described here.
Note that if this does not work instantly, don't panic, it seems like it takes a couple of minutes for keys to update on the server.
Wikis
GitHub saves wikis as git repos. The wiki is stored in a repository with the
same name but with a .wiki.git
suffix rather than .git
. For example, if you
clone the foobar
repo with
git clone git@github.com:myusername/foobar.git
then you clone the wiki for this repository with
git clone git@github.com:myusername/foobar.wiki.git
How many times has it been downloaded?
The GitHub API makes it possible to see how many times each release of a package has been downloaded. The following script can be used to determine how many times my timtam package has been downloaded.
import requests # Replace with your repository details owner = 'aezarebski' repo = 'timtam2' response = requests.get(f'https://api.github.com/repos/{owner}/{repo}/releases') releases = response.json() counts = [] for release in releases: print(f"Release: {release['name']}") for asset in release['assets']: print(f" Asset: {asset['name']}, Downloads: {asset['download_count']}") counts.append(asset['download_count']) print(f"Total download count: {sum(counts)}")