jonlabelle / crlf.py
#!/usr/bin/env python |
«»»Replace line breaks, from one format to another.»»» |
from __future__ import print_function |
import argparse |
import glob |
import os |
import sys |
import tempfile |
from stat import ST_ATIME , ST_MTIME |
LF = ‘ \n ‘ |
CRLF = ‘ \r \n ‘ |
CR = ‘ \r ‘ |
def _normalize_line_endings ( lines , line_ending = ‘unix’ ): |
r»»»Normalize line endings to unix (\n), windows (\r\n) or mac (\r). |
:param lines: The lines to normalize. |
:param line_ending: The line ending format. |
Acceptable values are ‘unix’ (default), ‘windows’ and ‘mac’. |
:return: Line endings normalized. |
«»» |
lines = lines . replace ( CRLF , LF ). replace ( CR , LF ) |
if line_ending == ‘windows’ : |
lines = lines . replace ( LF , CRLF ) |
elif line_ending == ‘mac’ : |
lines = lines . replace ( LF , CR ) |
return lines |
def _copy_file_time ( source , destination ): |
«»»Copy one file’s atime and mtime to another. |
:param source: Source file. |
:param destination: Destination file. |
«»» |
file1 , file2 = source , destination |
try : |
stat1 = os . stat ( file1 ) |
except os . error : |
sys . stderr . write ( file1 + ‘ : cannot stat \n ‘ ) |
sys . exit ( 1 ) |
try : |
os . utime ( file2 , ( stat1 [ ST_ATIME ], stat1 [ ST_MTIME ])) |
except os . error : |
sys . stderr . write ( file2 + ‘ : cannot change time \n ‘ ) |
sys . exit ( 2 ) |
def _create_temp_file ( contents ): |
«»»Create a temp file. |
:param contents: The temp file contents. |
:return: The absolute path of the created temp file. |
«»» |
tf = tempfile . NamedTemporaryFile ( mode = ‘wb’ , suffix = ‘txt’ , delete = False ) |
tf . write ( contents ) |
tf . close () |
return tf . name |
def _delete_file_if_exists ( filepath ): |
«»»Delete the file if it exists. |
:param filepath: The file path. |
«»» |
if os . path . exists ( filepath ): |
os . remove ( filepath ) |
def _read_file_data ( filepath ): |
«»»Read file data. |
:param filepath: The file path. |
:return: The file contents. |
«»» |
data = open ( filepath , ‘rb’ ). read () |
return data |
def _write_file_data ( filepath , data ): |
«»»Write file data. |
:param filepath: The file path. |
:param data: The data to write. |
«»» |
f = open ( filepath , ‘wb’ ) |
f . write ( data ) |
f . close () |
def main (): |
«»»Main.»»» |
parser = argparse . ArgumentParser ( |
prog = ‘crlf’ , |
description = ‘Replace CRLF (windows) line endings with LF (unix) ‘ |
‘line endings in files, and vice-versa’ ) |
parser . add_argument ( |
‘-q’ , ‘—quiet’ , |
help = ‘suppress descriptive messages from output’ , |
action = ‘store_true’ , |
default = False ) |
parser . add_argument ( |
‘-n’ , ‘—dryrun’ , |
help = ‘show changes, but do not modify files’ , |
action = ‘store_true’ , |
default = False ) |
parser . add_argument ( |
‘-w’ , ‘—windows’ , |
help = ‘replace LF (unix) line endings with CRLF (windows) line endings’ , |
action = ‘store_true’ , |
default = False ) |
parser . add_argument ( |
‘-u’ , ‘—unix’ , |
help = ‘replace CRLF (windows) line endings with LF (unix) ‘ |
‘line endings (default)’ , |
action = ‘store_true’ , |
default = False ) |
parser . add_argument ( |
‘-t’ , ‘—timestamps’ , |
help = «maintains the modified file’s time stamps (atime and mtime)» , |
action = ‘store_true’ , |
default = False ) |
parser . add_argument ( |
‘files’ , |
nargs = ‘+’ , |
help = «a list of files or file glob patterns to process» , |
default = ‘.’ ) |
if len ( sys . argv ) 2 : |
parser . print_help () |
sys . exit ( 2 ) |
args = parser . parse_args () |
if args . windows is True and args . unix is True : |
sys . stderr . write ( «Ambiguous options specified, ‘unix’ and ‘windows’. « |
«Please choose one option, or the other. \n » ) |
sys . exit ( 2 ) |
files_to_process = [] |
for arg_file in args . files : |
files_to_process . extend ( glob . glob ( arg_file )) |
if len ( files_to_process ) 0 : |
if args . quiet is False : |
sys . stderr . write ( ‘No files matched the specified pattern. \n ‘ ) |
sys . exit ( 2 ) |
if args . dryrun is True and args . quiet is False : |
print ( ‘Dry-run only, files will NOT be modified.’ ) |
for file_to_process in files_to_process : |
if os . path . isdir ( file_to_process ): |
if args . quiet is False : |
print ( «- ‘<0>‘ : is a directory (skip)» . format ( file_to_process )) |
continue |
if os . path . isfile ( file_to_process ): |
data = _read_file_data ( file_to_process ) |
if ‘ \\ 0’ in data : |
if args . quiet is False : |
print ( «- ‘<0>‘ : is a binary file (skip)» . format ( file_to_process )) |
continue |
if args . windows is True : |
new_data = _normalize_line_endings ( data , line_ending = ‘windows’ ) |
else : |
new_data = _normalize_line_endings ( data , line_ending = ‘unix’ ) |
if new_data != data : |
if args . quiet is False : |
if args . windows is True : |
if args . dryrun is True : |
print ( «+ ‘<0>‘ : LF would be replaced with CRLF» . format ( file_to_process )) |
else : |
print ( «+ ‘<0>‘ : replacing LF with CRLF» . format ( file_to_process )) |
else : |
if args . dryrun is True : |
print ( «+ ‘<0>‘ : CRLF would be replaced with LF» . format ( file_to_process )) |
else : |
print ( «+ ‘<0>‘ : replacing CRLF with LF» . format ( file_to_process )) |
tmp_file_path = «» |
if args . dryrun is False : |
try : |
if args . timestamps is True : |
# create a temp file with the original file |
# contents and copy the old file’s atime a mtime |
tmp_file_path = _create_temp_file ( data ) |
_copy_file_time ( file_to_process , tmp_file_path ) |
# overwrite the current file with the modified contents |
_write_file_data ( file_to_process , new_data ) |
if args . timestamps is True : |
# copy the original file’s atime and mtime back to |
# the original file w/ the modified contents, |
# and delete the temp file. |
_copy_file_time ( tmp_file_path , file_to_process ) |
_delete_file_if_exists ( tmp_file_path ) |
except Exception as ex : |
sys . stderr . write ( ‘error : <0>\n ‘ . format ( str ( ex ))) |
sys . exit ( 1 ) |
else : |
if args . quiet is False : |
if args . windows is True : |
print ( «- ‘<0>‘ : line endings already CRLF (windows)» . format ( file_to_process )) |
else : |
print ( «- ‘<0>‘ : line endings already LF (unix)» . format ( file_to_process )) |
else : |
sys . stderr . write ( «- ‘<0>‘ : file not found \n » . format ( file_to_process )) |
sys . exit ( 1 ) |
if __name__ == ‘__main__’ : |
main () |
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник
How to change line-ending settings
Is there a file or menu that will let me change the settings on how to deal with line endings?
I read there are 3 options:
Checkout Windows-style, commit Unix-style
Git will convert LF to CRLF when checking out text files. When committing text files, CRLF will be converted to LF. For cross-platform projects, this is the recommended setting on Windows («core.autocrlf» is set to «true»)
Checkout as-is, commit Unix-style
Git will not perform any conversion when checking out text files. When committing text files, CRLF will be converted to LF. For cross-platform projects this is the recommended setting on Unix («core.autocrlf» is set to «input»).
Checkout as-is, commit as-is
Git will not perform any conversions when checking out or committing text files. Choosing this option is not recommended for cross-platform projects («core.autocrlf» is set to «false»)
7 Answers 7
The normal way to control this is with git config
For details, scroll down in this link to Pro Git to the section named «core.autocrlf»
If you want to know what file this is saved in, you can run the command:
and the git global config file should open in a text editor, and you can see where that file was loaded from.
Line ending format used in OS:
- Windows: CR (Carriage Return \r ) and LF (LineFeed \n ) pair
- OSX, Linux: LF (LineFeed \n )
We can configure git to auto-correct line ending formats for each OS in two ways.
- Git Global configuration
- Using .gitattributes file
Global Configuration
In Linux/OSX
This will fix any CRLF to LF when you commit.
In Windows
This will make sure that, when you checkout in windows, all LF will be converted to CRLF .
.gitattributes File
It is a good idea to keep a .gitattributes file as we don’t want to expect everyone in our team to set their own config. This file should be placed in the repository root and. If it exists, git will respect it.
This will treat all files as text files and convert to OS’s line ending on checkout and back to LF on commit automatically. If you want to specify the line ending explicitly, you can use:
The first one is for checkout and the second one is for commit.
This will treat all .jpg images as binary files, regardless of path. So no conversion needed.
Or you can add path qualifiers:
For a repository setting solution, that can be redistributed to all developers, check out the text attribute in the .gitattributes file. This way, developers dont have to manually set their own line endings on the repository, and because different repositories can have different line ending styles, global core.autocrlf is not the best, at least in my opinion.
For example unsetting this attribute on a given path [. — text] will force git not to touch line endings when checking in and checking out. In my opinion, this is the best behavior, as most modern text editors can handle both type of line endings. Also, if you as a developer still want to do line ending conversion when checking in, you can still set the path to match certain files or set the eol attribute (in .gitattributes) on your repository.
Also check out this related post, which describes .gitattributes file and text attribute in more detail: What’s the best CRLF (carriage return, line feed) handling strategy with Git?
For me what did the trick was running the command
inside the folder of the project, I wanted it specifically for one project.
That command changed the file in path
at the end of the file. I suppose changing the file does the same trick as well.
Источник
Convert Unix line endings to Windows
I recently moved back to Windows from Linux. I have some files with CRLFs, some with LFs and some that are mixed. Is there a utility that will help me find all my Unix-touched files and convert them to proper CRLF terminated files?
The utility must run on Windows, not Linux. I have already moved. I’d rather not install Cygwin if I can avoid it.
14 Answers 14
You can convert them with the unix2dos utility on your Linux platform. There are unix2dos versions available for Windows as well.
If you have Perl installed you can also use this one liner:
Here is an easy and quick way.
Drag and drop the text file into Chrome (I don’t know about other browsers) and then cut and paste back into the original file 🙂
The one I found best for recursively going through folders, allowing file filters and allowing a simple search for «\r\n» and replacing it with just «\n» was Notepad++.
Notepad++ is one of the best, free, open source notepad programs for Windows. It is very simple and powerful. It handled the line ending search/replace just fine. A contractor check a bunch of .c and .h files in to our repository with Linux \r\n line endings, but since most people have standardized on Windows/Eclipse build tools, the files won’t build until the line endings are converted.
For example: sfk addcr -dir . -file .txt -norec
changes LF endings into CR/LF for Windows, on all .txt files of the current directory, but NOT within subdirectories (no recursion).
But this program does a lot more than just that.
On Cygwin, you can convert between Unix and «DOS» AKA Windows files using two built-in utilities:
Convert to DOS CR/LF format:
Convert back to Unix CR format:
The file is left in place with the same name.
I’m going to throw this solution out there. Git will do this. See this post about it
So theoretically you could do this to convert an entire tree
Change crlf to lf if you want to go the other way. NOTE: you’re not done yet, keep reading
Type git status to see which files will be affected. You might have to add lines like
etc to .gitattributes to avoid converting certain files. You can also explicit mark certain files as text
Then just repeat these 2 lines after you’ve edited .gitattributes
Then use git status again to see which files will be changed. When you’re sure all the files you want affected are listed by git status then commit
now check all the files out again
They should now have whatever your desired line endings are
** NOTE: If you were already using git skip the first 3 commands git commands. If you were not using git you can now delete the .gitattributes file and the .git folder.
** Back up your files: the git rm —cached -r deletes them all (although they are theoretically in your git repo (the .git folder) which is how they get restored by the last command git reset —hard . It’s just since files are getting deleted it’s probably best to back them up.
Источник