Git

Checkout single file from another branch


git checkout branch_name -- file.go

Squash commits


git rebase -i HEAD~[NUMBER OF COMMITS]

Reset local from remote


git reset --hard origin/master

git reset --hard origin/{branch_name}

Change the author of commits

  • Change just the very last commit - git commit --amend --author="John Doe <john@doe.org>"
Using Interactive Rebase
  • Identify the last “good” commit and provide its hash to the rebase command
git rebase -i -p 0ad14fa5

The editor will open, requesting you to mark all the commits you want to change with the edit (or e) keyword. Git will now walk you through each commit, giving you the chance to mold it as you desire:

Stopped at 5772b4bf2... Add images to about page
You can amend the commit now, with

    git commit --amend

Once you are satisfied with your changes, run

    git rebase --continue

Now, correct the author information and then continue to the next concerned commit object until you’ve edited all the commits you just marked:

git commit --amend --author="John Doe <john@doe.org>" --no-edit

git rebase --continue

ref

Find a deleted file in commit history

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}

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 dleted file’s contents

Remove file that was previous tracked and is now in .gitignore

Single file:


git rm --cached {file}

Whole folder:


git rm -r --cached {folder}


git diff a single file between commits


git diff 6c485e874de3:file.go origin/master:file.go

Checkout every repo under a group

Option 1 (one-liner)
for repo in $(curl -s --header "PRIVATE-TOKEN: your_private_token" https://<your-host>/api/v4/groups/<group_id> | jq -r ".projects[].ssh_url_to_repo"); do git clone $repo; done;

To include subgroups, add include_subgroups=true query param

https://<your-host>/api/v4/groups/<group_id>?include_subgroups=true
Option 2 (avoid needing a private token)

On the GitLab UI, navigate to https://<your-host>/api/v4/groups/<group_id>, copy the contents and save to a file (e.g. /tmp/group.json). Then, perform the same steps as before, instead using the file and avoiding the need to curl / a private token.

for repo in $(cat /tmp/group.json | jq -r ".projects[].ssh_url_to_repo"); do git clone $repo; done;

To ignore archived repositories:

for repo in $(cat /tmp/group.json | jq -r '.projects | .[] | select(.archived == false) | .ssh_url_to_repo'); do git clone $repo; done;

ref

Diff ranges

it diff range help

In other words, git diff foo..bar is exactly the same as git diff foo bar; both will show you the difference between the tips of the two branches foo and bar. On the other hand, git diff foo...bar will show you the difference between the “merge base” of the two branches and the tip of bar. The “merge base” is usually the last commit in common between those two branches, so this command will show you the changes that your work on bar has introduced, while ignoring everything that has been done on foo in the mean time. e