Table of Contents

Version Control Systems

SVN

Questions answered

How to recover from svn: E175002: Error setting property 'ignore': Could not execute PROPPATCH. error?

When committing I get the following error message:
svn: E175008: Commit failed (details follow):
svn: E175008: At least one property change failed; repository is unchanged
svn: E175002: Error setting property 'ignore':
Could not execute PROPPATCH.

This happens because client application has used “CRLF” end-of-line marker for svn:ignore property value (see Failed to execute WebDAV PROPPATCH when trying to commit a "ignore" file and JavaHL connector fails to commit svn:ignore property). To fix this re-save this property in Unix format. For that:
  1. Run svn propedit svn:ignore trunk. This will start external EDITOR (vi in my case).
  2. Now in vi type :e ++ff=unix1) and then :w! to save the content

Repeat this for all “damaged” properties. After that commit succeeds.

How to ignore files recursively?

Since v1.8: svn propset svn:global-ignores "*.o"

Mercurial

Questions answered

What should I do if I got “hg abort: changelog. no node!”

Perhaps, you also got a complain
$ hg status
$ abort: working directory has unknown parent 'd44a65b441c2'!

In this case do:

$ hg debugsetparents default
$ hg revert --no-backup --all -r tip

Git

Additional options

git config --global branch.autosetuprebase always

From autosetuprebase vs autosetupmerge:

Controls whether new branches should be set up to be rebased upon git pull, i.e. your setting of always will result in branches being set up such that git pull always performs a rebase, not a merge. Be aware that existing branches retain their configuration when you change this option.

git config --global pull.rebase preserve

From Make git pull --rebase preserve merge commits:

If a user is working on master, and has merged in their feature branch, but now has to git pull because master moved, with pull.rebase their feature branch will be flattened into master. This is because git pull currently does not know about rebase's preserve merges flag, which would avoid this behaviour, as it would instead replay just the merge commit of the feature branch onto the new master, and not replay each individual commit in the feature branch. Add a --rebase=preserve option, which will pass along --preserve-merges to git rebase.

Questions answered

What Git clients are available for Windows?

Revision selection (''HEAD~'' vs ''HEAD^'' vs ''HEAD@{}'')

  • HEAD~2 – 2 commits older than HEAD
  • HEAD^2 – the second parent of HEAD if HEAD was a merge, otherwise illegal
  • HEAD@{2} – refers to the 3rd listing in the overview of git reflog

See also What's the difference between HEAD^ and HEAD~ in Git.

How to undo last commit?

From Git undo last commit:
  • git reset --hard HEAD^
    Will revert all current changes and revert to previous commit. The commit on the top is destroyed.
  • git reset HEAD^
    Will keep all current changes and switch to previous commit. The commit on the top is kept.
  • git reset --hard
    Will revert all current changes.
  • Or make changes on top (git rm, git add, …) and add them to previous commit with:
    git commit --amend
  • To revert changes for some file or directory use:
    git checkout <file>
  • To undo commit f25fcf53 by follow-up rollback commit:
    git revert f25fcf53

How can I squash my last N commits together?

From How can I squash my last X commits together using git?:

Suppose you're on master and you want to squash the last 12 commits into one:

  1. git reset --hard HEAD~12
  2. git merge --squash HEAD@{1} (needs additional quoting on Windows e.g. git merge --squash "HEAD@{1}")
  3. git commit

The same:

  1. git reset --soft HEAD~12
  2. git commit

To apply changes to remote repository, do:

  • git push --force origin master (replace master with the name of your current branch).
    With eclipse: Team → Push Branch… and check Force overwrite of branch on remote if it exists and has diverged.

How to remove a commit?

Suppose ec5ef1e9 is commit hash you want to remove, then below will do the job:

git rebase -p --onto ec5ef1e9^ ec5ef1e9

How to change the author or message of Git commit?

From Change commit author at one specific commit:

For example, if your commit history is A-B-C-D-E-F with F as HEAD, and you want to change the author of C and D then you would:

  1. git rebase -i B
    Change the lines for both C and D to edit.
    Once the rebase started, it would first pause at C.
  2. git commit --amend --author="Author Name <email@address.com>"
  3. git rebase --continue
    It would pause again at D.
  4. git commit --amend --author="Author Name <email@address.com>" again
  5. git rebase --continue
    This would complete the rebase.

To change the message:

  • git commit --amend (will launch vim to enter new message) or git commit --amend -m "New commit message"
    Will amend the top of the current branch.

The same technique can be used to insert commit into the history as alternative to this one:

  1. Commit to the changes to the HEAD and git rebase -i B where B is some commit in the past after which you want to insert the given one.
  2. In the editor, reshuffle lines in order which is needed. After save+exit rebase will continue and reorder commits.

How to exclude a particular file from commit?

  1. Update the version of file in index to one in HEAD minus one commit thus effectively undoing the change:
    git reset HEAD~ <file>
  2. Replace the content of the file in working tree (from history or from stash) and then do:
    git add -u <file>
  3. After that do git commit --amend or git rebase --continue.

:OPT: Alternative solution is to rewrite the whole history with the given file removed:

git filter-branch --prune-empty --tree-filter 'rm -f file_to_remove' --tag-name-filter cat -- --all

How to rewrite git history and replace EOL from CRLF to LF?

  1. git filter-branch --force --prune-empty --tree-filter 'git ls-files | xargs file | sed -n -e "s/\(.*\): .*text.*/\1/p" | xargs dos2unix' --tag-name-filter cat -- --all
  2. git push --force --all
  3. git push --force --tags

How to split directories into separate git repository preserving commit history?

For one directory mydir in repository myrepo one can do the following:
  1. Clone repo (for safety):
    git clone myrepo mynewrepo
  2. cd mynewrepo
  3. Filter out commits which are not relevant to mydir:
    git filter-branch --prune-empty --subdirectory-filter mydir --tag-name-filter cat -- --all
    :OPT: git filter-branch --prune-empty --subdirectory-filter mydir HEAD

Above method has one disadvantage which is written in documentation:

The result will contain that directory (and only that) as its project root.

To move the directory one level deeper requires another history rewrite… hence it's better to take another approach:

  1. Clone repo:
    git clone my-repo my-repo-copy
  2. cd my-repo-copy
    • Remove all except mydir1, mydir2, …:
      git filter-branch --tree-filter 'ls -1 | egrep -v "^(mydir1|mydir2)" | xargs rm -rf .gitattributes .gitignore' 2> /dev/null" HEAD
      cd ..
    • :OPT: … or move mydir1, mydir2, … to a temporary directory and split :
      git filter-branch --tree-filter "mkdir tmpdir; mv mydir1 mydir2 tmpdir 2> /dev/null" HEAD
      git subtree split -P tmpdir -b tmpbranch
      cd ..
  3. Create new repo:
    mkdir new-repo && cd new-repo && git init
  4. Pull changes from branch:
    git pull ../my-repo-copy tmpbranch
  5. :OPT: Additionally one can add more commits from another repository:
    • git fetch ../another-repo --no-tags +tmpbranch:tmpbranch
    • git rebase tmpbranch
  6. Finally push to origin:
    git remote add origin git@github.com:my-user/new-repo.git && git push origin -u master

How to push all commits but the last one to origin?

  1. git checkout HEAD~
  2. git push origin HEAD:master
  3. git checkout master

How to see all outgoing commits?

git cherry -v to list all outgoing commits (to be pushed) for current branch.

How to fetch changes from upstream?

From Update my github repo which is forked out from another project:
  1. git remote add upstream https://github.com/project/project.git to add new upstream URL
  2. :OPT: And either:
    • git pull upstream [branch to merge] which is the same as git fetch upstream + git merge (for example: git pull upstream master, git pull upstream release_2016-01-20)
    • or git fetch upstream + git rebase to rebase your work without needing a merge

See here about how merge differs from rebase.

How to work with branches?

  • git branch show all local branches (current branch is marked)
  • git branch <branch> to create new branch and start working in it
  • git checkout <branch> to change the branch, e.g. git checkout master will switch the repository to main branch
  • git branch -m <branch> <new name> to rename local branch
  • git branch -D <branch> to delete the branch
  • git branch -f master HEAD to switch master branch, e.g. git branch -f master 010203A to switch to particular commit (see How to move master to HEAD)

How to create a branch to implement new feature if origin/master branch already contains some features different from upstream/master?

To create a new branch for feature “myfix”:
  1. git checkout -b myfix
  2. Make fixes or implement a feature…
  3. git fetch upstream
  4. Rebase current branch on the top of upstream/master with differences from master..myfix incorporated:
    git rebase --onto upstream/master master
  5. git push origin myfix
  6. Submit pull request…

If you need to refine after submitting a pull request:

  1. Do some local master changes
  2. git checkout myfix
  3. Replay these changes on branch:
    git rebase master
  4. Make fixes; probably do
    git commit --amend
  5. Replay on the top of upstream/master:
    git rebase --onto upstream/master master
  6. git push origin myfix -f

If any conflicts during the rebase, use git checkout --theirs <file> to replace the file with your version (during rebase --ours is referring upstream/master).

How to remove a remote branch?

From How do I delete a Git branch both locally and in Github:

Use git push origin --delete branch which is the same as git push origin :branch.

How to rename a remote branch?

From git: renaming branches remotely and Renaming remote git branch:
  • git branch new-branch-name origin/old-branch-name
  • git push origin new-branch-name will add new branch
  • git push origin :old-branch-name will remove old branch

or

  • git push origin :old-branch-name will remove remote old branch
  • git push origin local-branch-name:new-branch-name will push local branch to remote but with new name

How to rename a remote tag?

  • git tag new_tag old_tag will create a new tag pointing to same commit as old tag
  • git push --tags will push new tag to remote
  • git push origin :refs/tags/old_tag will delete the old tag from remote

How to compare?

A file with another branch:
  • git diff <branch> <file>, e.g. git diff upstream/master pom.xml

Two tags:

  • Combined diff:
    git diff --color -M tags/one tags/two
  • With log message for each commit:
    git log --color --full-diff -p -M tags/one..tags/two

How to log history for removed file?

git log --full-history -- /path/to/removed/file

How to list all commits by given user?

git log --author="Jon Smith"

How to find the commit where the bug was introduced?

git bisect – это средство для двоичного поиска коммита, который все сломал. Допустим вы знаете коммиты где бага не было, и где баг уже есть. Цель – найти коммит, который посадил этот баг, за минимальное количество шагов. Откатываемся к коммиту, который точно посередине. Если бага в этой точки нет, то проблемный коммит справа, иначе он слева. Повторяем пока не найдём. Особенность git bisect-а, что он умеет правильно обрабатывать нелинейные куски истории.

Git blame: how to go back in commit history?

After you have listed the latest commit reported by git blame (assuming that is f25fcf53), do the following iteratively until you find the needed commit (perhaps you need to make line number adjustment on each iteration):

git blame -n -L 810,+40 f25fcf53^ file.php

How to display a given commit as a diff?

  • git show f25fcf53
  • git diff f25fcf53^!

How to format a given commit as a patch?

git format-patch --stdout -<commits count> <commit hash>

For example

git format-patch -1 f25fcf53

will create a patch for one particular commit giving it a name derived from comment message. This patch can later be applied via

git am <file>

How to configure password for remote repository?

When and how does git use deltas for storage?

  1. When optimizing the local storage. Git by default regularly runs git gc --auto to optimize the storage, which in turn runs git repack when necessary.
  2. When sending the bulk of changes to the client on git fetch. In this case a thin pack is created.

How to reduce repository size?

:WARN: Use below instructions with care. Think twice about what you really need to be kept.
  1. Delete all tags:
    git tag -d $(git tag)
  2. Delete all local branches except master:
    git branch -D $(git branch | grep -v "master")
  3. Delete all remote branches except master:
    git branch -r -D $(git branch -r | grep -v "master")
  4. Remove reflog entries not reachable from the current tip:
    git reflog expire --all --expire=all
  5. Run one of (more or less equivalent):
    • git repack -a -d -f --depth=500 --window=500 --threads=2
    • git gc --prune=now --aggressive

How to integrate Cygwin Git into Visual Studio code?

Based on solution git.c:
  • Compile the following C program (change path to wrapper script accordingly) gcc git-wrapper -o git-wrapper.exe:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(int argc, char **argv)
    {
        char buf[4000] = "/bin/bash -c 'C:/Applications/CygWin/git-wrapper.sh";
        int rest = sizeof(buf) - strlen(buf) - 2; /* 2 for "'\0" */
     
        for (int i = 1; i < argc; i++) {
            rest -= strlen(argv[i]) + 3; /* 3 for " \"\"" */
            if (rest < 0) {
                fprintf(stderr, "arguments too long\n");
                return 1;
            }
            strcat(buf, " \"");
            strcat(buf, argv[i]);
            strcat(buf, "\"");
        }
        strcat(buf, "'");
        return system(buf);
    }
  • Created wrapper script:
    #!/bin/bash
     
    wrap_output=""
    argv=("$@")
     
    for ((i = 0; i < $#; i++))
    do
        arg="${argv[$i]}"
        if [ $i = 0 -a "$arg" = 'rev-parse' ]
        then
            wrap_output=yes
        elif [[ -n "$arg" && "$arg" != -* ]]
        then
            argv[i]=`cygpath -u "$arg"`
        fi
    done
     
    if [ $wrap_output ]
    then
        if out=`git "${argv[@]}"`
        then
            if [ -n "$out" ]
            then
                if [[ $out = -* ]]
                then
                    echo "$out"
                else
                    cygpath -w "$out"
                fi
            fi
        else
            x=$?
            echo "$out"
            exit $x
        fi
    else
        exec git "${argv[@]}"
    fi
  • Configure VS Code to use it: add "git.path": "C:\\Applications\\CygWin\\git-wrapper.exe" to %APPDATA%\Code\User\settings.json.

See also:

Error The requested URL returned error: 403 while accessing…

From Can't clone any repository in Git:

Update git to v1.7.x.

1) Check here for more information about this option
software/vcs.txt · Last modified: 2012/06/05 11:40 by dmitry
 
 
Recent changes RSS feed Driven by DokuWiki