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
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;
Diff ranges
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