Git

July 8, 2020 Application 7 minutes, 45 seconds

  • HEAD^ is one commit before HEAD
  • HEAD~4 is four commits before HEAD

Check current urls:

git remote -v

Switch urls:

git remote set-url origin NEWURL

Compare change

git remote -v

Push to new remote

git push -u origin master

find . -maxdepth 1 -type d -exec git --git-dir={}/.git --work-tree=$PWD/{} pull \;

git config --global http.proxy http://proxy.company.com:3128

or in .git/config

[http]
    proxy = http://proxy.company.com:3128

or temporarly as command line argument

-c http.proxy http://proxy.company.com:3128

git config --global http.sslVerify=false

or in .git/config

[http]
sslVerify = false

or temporarly as command line argument

-c http.sslVerify=false

git rev-parse --abbrev-ref HEAD

git remote add github https://github.com/USER/repo.git
git push/pull origin
git push/pull github

When the origin is at github vice versa.

git remote set-url –add origin https://github.com/USER/repo.git
git push/pull origin

When the origin is at github vice versa. Now, origin will targed the Gitlab as well as Github remotes

git config [--global] --edit

git config --global core.autocrlf false
git config --global core.eol lf

GIT_CURL_VERBOSE=1 GIT_TRACE=1 git pull

even more output:

set -x; GIT_TRACE=2 GIT_CURL_VERBOSE=2 GIT_TRACE_PERFORMANCE=2 GIT_TRACE_PACK_ACCESS=2 GIT_TRACE_PACKET=2 GIT_TRACE_PACKFILE=2 GIT_TRACE_SETUP=2 GIT_TRACE_SHALLOW=2 git pull origin master -v -v; set +x

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Small CLI script to list basic overview of our Github repositories

- Access and repositories are based upon the user's permissions
- Default ouput is a SingleTable (fancier) but ASCII Table is supported as well
- Show last commit only since a defined period of time to limit required API calls

Install dependencies with 'pip3 install --user PyGithub, terminaltables' or appropriate command
"""
__version__ = "1.0.0"

from datetime import datetime, timedelta
import argparse
from github import Github
from terminaltables import AsciiTable, SingleTable

def main(args):
    """ entry point """
    g = Github(args.token)

    data = [['Name', 'URL', 'Tags', 'Branches', 'Last Commit']]

    since = datetime.now() - timedelta(days=args.days)

    for repo in g.get_user().get_repos():
        # to see all the available attributes and methods
        # print(dir(repo))
        commits = repo.get_commits(since=since)
        date = 'unknown'
        author = 'unknown'
        try:
            if commits.totalCount > 0:
                last_commit = commits[0]
                date = last_commit.last_modified
                author = last_commit.author.login
        except:
            pass # empty repo found ^^
        name = repo.name
        url = repo.clone_url
        tags = []
        for tag in repo.get_tags():
            tags.append(tag.name)
        branches = []
        for branch in repo.get_branches():
            branches.append(branch.name)
        data.append([name, url, '\n'.join(tags), '\n'.join(branches), f"{date} by {author}"])

    if (args.a):
        table = AsciiTable(data)
    else:
        table = SingleTable(data)
    table.inner_row_border = True
    print(table.table)

if __name__ == "__main__":
    """ Executed from the commandline"""
    parser = argparse.ArgumentParser(description='Terminal Github Overview for Innio')
    parser.add_argument('-t', '--token', action='store', required=True, help='your Github API token')
    parser.add_argument('-d', '--days', action='store', type=int, default=1, help='list commits since x days')
    parser.add_argument('-a', action='store_true', default=False, help='use simple ASCII table as output')
    parser.add_argument('-v', action='version',version='%(prog)s (version {version})'.format(version=__version__))
    args = parser.parse_args()
    main(args)

How to remove a submodule from a git repository1

  1. Remove the relevant .gitmodules section
  2. git add .gitmodules
  3. Remove the relevant .git/config section
  4. git rm --cached /path/to/submodule (no trailing slash)
  5. git commit -m "Remove submodule"
  6. rm -rf /path/to/submodule

git config core.filemode false

git checkout feature
git merge master

This results in a merge commit and may pollute the commit log but it preserves history in contrast to rebase

Don't do that on public branches where multiple devs are working on as this will rewrite the commit history according to your local branch!

git checkout feature
git rebase master

git push -d <remote_name> <branch_name>
git branch -d <branch_name> # only delete a local branch

-D forces the deletion when the branch is not merged in

# Delete local branches that do not exist on remote anymore
git remote prune origin

# alternative approach
git push --delete origin <tag>
git tag -d <tag> # only delete local tag

Use case: After a git push you realize a commit is wrong

Undo: git revert <SHA>

This will create a new commit that reverts the specified commit

Use case: Typo in commit message "before" git push

Undo: git commit --amend -m "Fixed commit message"

This will update and replace the most recent commit. Be aware that staged changes will be included as well so in order to just fix the commit message ensure that there are no staged changes.

Use case: After editing local files nothing is working and you want to undo everything you have done.

Undo: git checkout -- <filename>

This will modify the file to a state known to git. Be aware that you cannot recover this as nothing was ever commited!

Use case: You made local commits (not yet pushed) and you want to undo the last four commits without any leftovers.

Undo: git reset [--hard] <last good SHA>

This will rewind the history of your repo back to the specified SHA as if the commits never happened. By default, git reset only removes the commits but not the content on disk. --hard option will also remove the changes on disk.

Use case: After git reset --hard you changed your mind and want the changes back

Undo: git reflog

This will show a list of times Use case HEAD changed.

Use case: You made some commits accidenttally on master instead a feature branch.

Undo: git branch feature, git reset --hard origin/master, git checkout feature

This will

  1. create a branch named "feature" pointing to the most recent commit while still in master
  2. Rewinds master back to origin/master before your new commits while they still exist on "feature" branch
  3. Switch to the new "feature" branch with all the recent work

Use case: Branch named "feature" branch started from master but you realized that after syncing master with origin/master that master was far behind. Now commits on "feature" should start now instead of being behind.

Undo: git checkout feature, git rebase master (compare Integrate branches)

This will

  1. locate the common ancestor between "feature" and master
  2. reset "feature" to that ancestor while holding all commits in a temporary area
  3. advance "feature" to the end of master and replay all commits from the temporary area after master's last commit

Use case: You have a dozen commmits but only want some of them and the rest should disappear

Undo: git rebase -i <earlier SHA>

This will start rebase in interactive mode like above but before replaying any commits you have the chance to modify each commit.

  • pick is the default action meaning the commit will be applied
  • to delete commits just delete the line
  • reword to preserve the content of the commit and rewrite the commit message. Be aware that you cannot edit the message here as rebase ignores everything after the SHA column. After finishing rebasing you will be prompted for new messages.
  • fixup or sqash to combine commits "upwards". sqash will create a new commit and ask for a new commit message. fixup will use the message from the first commit in the list.
  • reorder commits by changing the order before saving

Use case: You forgot to include a file in an earlier commit. You haven't pushed yet but it also is not the most recent commit (--amend won't work)

Undo: git commit --sqash <SHA of the earlier commit>, git rebae --autosqash -i <even earlier SHA>

This will

  1. create a new commit with a message like "sqash! Earlier commit"
  2. launch an interactive rebase with any sqash! (and fixup!) commits already paired to the commit target

Use case: Accidenttaly, you added a wrong file to the repo

Undo: git rm --cached <filename>

This will remove the file from git but preserves the content on disk

Start the rebase at the last "good" commit

git rebase -i -p COMMITHASH

or start from the initial commit with

git rebase -i --root $tip

After this command a text editor will open. Edit the keywords at the beginning of the line, in this case edit allows us to modify the commits. After saving the file the first commit to be edited will be selected. Now you can run e.g.

git commit --amend --author="Michael <allaman@rootknecht.net>" --no-edit

to modify the author. Then run

git rebase --continue

to go to the next marked commit. After rebasing run

git push --force-with-lease

to push your modifications.