How to patch on Windows? - windows

Given a (source) patch file, what's the easiest way to apply this patch on the source files under Windows?
A GUI tool where I can visually compare the unchanged-changed source lines would be great.

A good way to apply a patch file under Windows OS is using Git.
As I understood, Git is a version control solution like SVN.
Here is a guideline to apply a patch :
First of all, download the latest release of the Windows Git Edition here :
GIT
With the cmd prompt, change directory to the patch file and files to patch
Now you can use the following command line :
git apply --ignore-space-change --ignore-whitespace --whitespace=nowarn file.patch

Not that since Git 2.3.3 (March 2015), you can use git apply --unsafe-paths to use git apply outside a git repo.
See commit 5244a31 by Junio C Hamano (gitster)
"git apply" was not very careful about reading from, removing, updating and creating paths outside the working tree (under --index/--cached) or the current directory (when used as a replacement for GNU patch).
The documentation now includes:
--unsafe-paths:
By default, a patch that affects outside the working area (either a Git controlled working tree, or the current working directory when "git apply" is used as a replacement of GNU patch) is rejected as a mistake (or a mischief).
When git apply is used as a "better GNU patch", the user can pass the --unsafe-paths option to override this safety check.
This option has no effect when --index or --cached is in use.
So if you have git installed, git apply could help, even outside of any git repo.

Patch for Windows is what you're looking for.

WinMerge is awesome.
http://winmerge.org/

Related

Git post-checkout hook on windows

I installed git 2.28.0 on windows.
In fact, i can't find post-checkout.sample hook in the hooks repository under /.git repository.
Is post-checkout.sample hook supported on windows ?
When i installed the same version of git on linux i found the post-checkout.sample hook.
I even tried with the git 2.23.0 version and i had the same problem.
I tried to create post-checkout that print a simple message "hello". But it doesn't work. However when I copied this file in pre-commit it works.
Any suggestions?
It seems that it doesn't work on an empty repository.
I just committed a file in my repository and when i excute git checkout -b new_branch, the post-checkout hook worked.
I never saw a post-checkout.sample in mingw64/share/git-core/templates/hooks/ of a Git For Windows distribution.
But that hook should work, provided you make it:
a file named "post-checkout"
a bash script (see an example here)
in your repo/.git/hooks folder
There was actually a proposal (RFC) for a post-checkout.sample in 2009, but it was not picked up at the time.
The question was asked (also in 2009):
I also noticed that the
post-checkout sample does not exist when I init a new archive. Is this a
bug?
No, it's security.
Hooks are executable files and shouldn't blindly be
copied around for security reasons.

Can I disable a particular git command?

With new versions of git new commands have been added which I will probably never use.
Is there a way I can disable these commands so that I my tab completion is faster?
For ex: before, git check<tab> would autocomplete to git checkout
But now git check<tab> doesn't tab complete due to there being git check-mailmap in the newer git version.
This is just one of the example.
Alternatively it would be great if I could "force" git to tab-complete "check" to checkout .
Edit: I use vanilla bash with no extra modifications
The official way is to use the configuration completion.commands and remove the ones you don't want:
git config --global completion.commands -check-mailmap
However, you can do even more. There is a hack in __git_main() used for testing that you can abuse to do what you want:
GIT_TESTING_PORCELAIN_COMMAND_LIST="$(git --list-cmds=list-mainporcelain,alias)"
This will force Git's completion to show only the main commands (and aliases).
You need Git v2.18 or newer for these to work.
To see how to remove items from the autocomplete, see FelipeC's answer.
An alternative is to use git aliases to create shorter alternatives to the commands you commonly use. For example:
git config --global alias.co checkout
Now you can type git co to check out files.

Add symlink file as file using Git on Windows

I have a big (more than 1000 files) VS C# project in git. I need to create a small demo project and use ten files from the big project. To create this new project, I added ten files with mklink (symlink) from the big project to the small. All changes in corresponding files in the big and small project are identical. Now I need to add the small project to a different (my own) git repo.
But symlink will not add in git :
(error: readlink("X.cs"): Function not implemented)
How to add the X.cs (symlink) file in git as a regular file?
I need all changes in X.cs (in big project) to be moved to X.cs (small project).
If adding symlinks to the index fails with error error: readlink("..."): Function not implemented, try to find this line in the local or global config:
[core]
symlinks = false
You need to set symlinks = true for a successful push. Default value (=true) if parameter does not exist or is not working correctly and it depends on the settings with which the repository was created.
Hardlinks do not work with GIT, as the file and hardlink are stored as separate files.
It works the same with git version 2.8 or above (I did not check versions less than 2.8)
The current answer(s) are out-of-date and require revision given recent changes.
The solutions given there isn't enough and isn't working.
There are still issues with the latest Git 2.12 on Windows (February 2017, 18 months after the OP's question)
In the context of working on what was called git-new-workdir in 2015 (the ability, form one clone, to have multiple working tree: this ended up being called git worktree), the Git developers were asking how to reference those worktrees from the main cloned repo.
Would they be using ln? or its Windows equivalent mklink?
This thread, at the time, highlighted the issues:
When running on Windows in MinGW, creating symbolic links via ln always failed.
Using mklink instead of ln is the recommended method of creating links on Windows
That might be true, but not ideal: "Git Bash Shell fails to create symbolic links" does mention:
For my setup, that is Git for Windows 2.11.0 installed on Windows 8.1 export MSYS=winsymlinks:nativestrict does the trick as explained here: git-for-windows/pull/156
It's important to launch the Git Bash shell as administrator as on Windows only administrators could create the symbolic links. So, in order to make tar -xf work and create the required symlinks:
Run Git Bash shell as an administrator
Run export MSYS=winsymlinks:nativestrict
Run tar
See also "Git Symlinks in Windows", where the setup now (Git for Windows 2.10+) include symlink support:
You need to specify that during the clone:
git clone -c core.symlinks=true <URL>
And your CMD session needs to be run as admin.
Needless to say imposing that prerequisite on Windows users is a no-go (Windows in enterprise generally come with limited or no privilege elevation)
Yet, PR 156 does represent some Windows support for symlink, released in Git For Windows 2.10 (Sept. 2016).
It is telling that git worktree ended up implementing the multiple working tree reference... by not relying on symbolic links and by making the borrowee and borrowers aware of each other.
When you are done with a linked working tree you can simply delete it.
The working tree's administrative files in the repository will eventually be removed automatically (see gc.pruneworktreesexpire in git config), or you can run git worktree prune in the main or any linked working tree to clean up any stale administrative files.
So no symbolic link there.
git has problems with individual file links but it has no problem with directory symbolic links(mklink /d ). Therefore move your image files to another directory in your big project and create directory link in your git repo to this directory.
See below for example.
P:\denemeler\gitdeneme1>mklink /d linkDirectory P:\puzzles
Created symbolic link : linkDirectory <<===>> P:\puzzles
P:\denemeler\gitdeneme1>git status
On branch master Untracked files:
(use "git add ..." to include in what will be committed)
linkDirectory/
nothing added to commit but untracked files present (use "git add" to
track)
P:\denemeler\gitdeneme1>git add linkDirectory
P:\denemeler\gitdeneme1>git status
On branch master Changes to be
committed: (use "git reset HEAD ..." to unstage)
new file: linkDirectory/Juggle Fest Question.txt
new file: linkDirectory/jugglefest.txt
new file: linkDirectory/triangle.txt
new file: linkDirectory/triangleQuestion.txt
P:\denemeler\gitdeneme1>git commit -m "new files"
[master 0c7d126] new
files 4 files changed, 14150 insertions(+) create mode 100644
linkDirectory/Juggle Fest Question.txt create mode 100644
linkDirectory/jugglefest.txt create mode 100644
linkDirectory/triangle.txt create mode 100644
linkDirectory/triangleQuestion.txt
P:\denemeler\gitdeneme1>echo "aa" > p:\puzzles\newFile.txt
P:\denemeler\gitdeneme1>git status
On branch master Untracked files:
(use "git add ..." to include in what will be committed)
linkDirectory/newFile.txt
nothing added to commit but untracked files present (use "git add" to
track)
Git does indeed have trouble with symlinks on Windows. However, I don't think you even need symlinks for your problem. A simple workaround is to write a small *.bat script to copy the files in question from one repository to another on demand. With symlink, you don't need to run a script, which saves you a few seconds, but you get a problem that you can accidentally change file in small repository and have unwanted modification in big repository.
Looks like all your simlinks located in one ntfs partition, if it is true, you can renew all simlinks to hardlinks, by some script with command, mklink /h...
Hardlinks friendly for any CVS.

GUI for conflicts resolution

I have a patch and directory to be patched. I can apply the patch with
patch -p0 --merge my.patch
The conflicts are marked then properly (using "<<<<", "====" and so on).
The question is - is there a graphical tool that allow to resolve conflicts marked in such a way? Or is there any other way of graphical conflict resolution in the case i have only a patch and a set of files (directory) to be patched? I tried Kompare but it doesn't work well.
ECMerge, the tool I work on, has a command to do this off-the-shelf, calling ecmerge.exe --open-conflict mydocument.c from the command line does the job (there is a shell extension for Windows/Linux and Mac as well and menu item in the GUI). It offers you the usual 2 or 3-way merge view one would expect in this situation.
ECMerge can also do the job of patch directly and let you preview and merge completely in the GUI with its Patch Import feature.
In case you are using git repository then, instead of using a patch command you
can fire the following command, as shown below :
$ git am -3 < /tmp/0001-Added-feature-hello.patch
Applying: Added feature hello
Using index info to reconstruct a base tree...
M code.c
Falling back to patching base and 3-way merge...
Auto-merging code.c
CONFLICT (content): Merge conflict in code.c
error: Failed to merge in the changes.
Patch failed at 0001 Added feature hello
Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
To resolve the conflict using GUI fire the following command :
$ git mergetool --tool=meld

Can git and subversion play nice together?

I have recently decided to take the git plunge, and am really enjoying using git, even on Windows.
My current open source project lives on subversion, all devs are familiar with subversion so I would like to keep subversion as the "source of truth" for now.
Nonetheless, I want to use git, so I went ahead and created a copy of the source on github using git svn. All my work is done against the source in github and I push my changes to github. Once every few days I also push my changes to svn and rebase.
The initial import seemed to go ok, but now every time I do a "git svn rebase" I keep on getting conflicts, even on files I have not changed in my get repository. This is causing me much pain.
Eg.
$ git svn rebase
First, rewinding head to replay your work on top of it...
Applying: Added git ignore file
c:/Users/sam/Desktop/MediaBrowserGit/trunk/.git/rebase-apply/patch:12: trailing
whitespace.
*/obj/*
error: .gitignore: already exists in index
Using index info to reconstruct a base tree...
:12: trailing whitespace.
*/obj/*
warning: 1 line adds whitespace errors.
Falling back to patching base and 3-way merge...
Auto-merging .gitignore
CONFLICT (add/add): Merge conflict in .gitignore
Failed to merge in the changes.
Patch failed at 0001 Added git ignore file
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
rebase refs/remotes/git-svn: command returned error: 1
My questions:
Is there any way I can tell git to sync itself up with svn using svn as the source, so I can start with a clean slate. (export latest, check in changes and reset the svn refs somewhere)
Are there any tips and tricks to getting this scenario to work consistently?
Should I have the core.safecrlf and core.autocrlf options set to true? It seems I will need a bit of hoop jumping.
Related:
http://kerneltrap.org/index.php?q=mailarchive/git/2008/4/16/1450834/thread
http://markmail.org/message/vaois4kkr5ggugqs#query:git%20crlf+page:1+mid:i4flex6vmt5tdala+state:results
http://code.google.com/p/msysgit/issues/detail?id=271
It seems getting line endings right is a bit of a black art.
(I realize that this question probably needs to be expanded, please comment on the places that need expanding)
Are you getting line-ending conflicts? Git has a few configuration properties you can set that change how it handles the end of line characters. I have the following set:
# this makes git NOT attempt to convert line endings on commit and checkout
core.autocrlf=false
# this makes git check if the conversion done by autocrlf would be reversible
# this is probably not required because I do not have autocrlf turned on
core.safecrlf=true
Note that I am on windows, all my coworkers are on windows and I am interfacing with SVN through git-svn. These settings seem to do the trick for me.
(source: codinghorror.com)

Resources