Git notes

Home

git-logo.png

Table of Contents

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)}")

GitLab

ssh keys

See my notes on how to use these with GitHub.

Author: Alexander E. Zarebski

Created: 2024-08-06 Tue 11:35

Validate