2010-06-10 26 views
24

Tôi đang cố gắng lưu trữ một số tập lệnh Windows PowerShell trong kho lưu trữ Mercurial. Có vẻ như trình chỉnh sửa PowerShell thích lưu tệp dưới dạng Unicode UTF-16. Điều này có nghĩa rằng có rất nhiều \0 byte, đó là những gì Mercurial sử dụng để phân biệt giữa các tệp "văn bản" và "nhị phân". Tôi hiểu rằng điều này làm cho không có sự khác biệt về cách Mercurial lưu trữ dữ liệu, nhưng nó có nghĩa là nó hiển thị các khác biệt nhị phân, rất khó đọc. Có cách nào để nói với Mercurial rằng đây thực sự là các tập tin văn bản? Có lẽ tôi sẽ cần phải thuyết phục Mercurial sử dụng một chương trình khác biệt Unicode nhận thức bên ngoài cho các loại tệp cụ thể.Bắt hiển thị khác có thể đọc được trong Mercurial trên các tệp Unicode (MS Windows)

+0

Cụ thể, vấn đề của tôi là với trang "Văn bản khác" trong "Commit "công cụ sử dụng TortoiseHg, thường hiển thị một bản tóm tắt tốt đẹp về các thay đổi trong tệp đã chọn, nhưng hiển thị rác với các tệp UTF-16. –

+0

@orad: Tính đến ngày 22 tháng 9 năm 2010, tôi vẫn chưa tìm thấy câu trả lời. –

+0

Câu trả lời BOM.py sẽ hoạt động. Chỉ cần sao chép toàn bộ nội dung vào một tệp và sau đó chỉnh sửa (hoặc tạo) tệp người dùng \ yourname \ Mercurial.ini của bạn và trong dòng "[extensions]" (thêm nó, nếu không có dòng đó), hãy thêm một dòng có tên = tệp (như "bom = C: \ path \ to \ the \ bom.py"). – Jaykul

Trả lời

2

Tôi đã làm việc này bằng cách tạo tệp mới với NotePad ++ và lưu tệp dưới dạng tệp PowerShell (đuôi mở rộng .ps1). NotePad ++ sẽ tạo tệp dưới dạng tệp ANSI văn bản thuần túy. Khi đã tạo, tôi có thể mở tệp trong trình chỉnh sửa PowerShell và thực hiện bất kỳ thay đổi nào nếu cần mà không có trình chỉnh sửa sửa đổi mã hóa tệp.

Tuyên bố từ chối trách nhiệm: Tôi đã gặp phải điều này chỉ vài giây trước và vì vậy tôi không chắc liệu có bất kỳ hậu quả nào hay không nhưng kịch bản của tôi dường như hoạt động bình thường và các khác biệt của tôi hiển thị độc đáo.

+0

Chuyển đổi sang UTF-8 cũng hoạt động với các tệp .strings trong Xcode (genstrings tạo ra UTF-16LE theo mặc định) – hop

3

Điều này có thể không liên quan đến bạn; đọc đoạn cuối nếu nó không giống như nó.

Tôi không chắc liệu đây có phải là những gì bạn cần hay không, nhưng tôi cần có sự khác biệt với nội dung UTF-16LE hơn là "tệp nhị phân khác" - khi tôi tìm kiếm khoảng vài tháng trước Tôi tìm thấy một chủ đề và lỗi thảo luận về nó; here's part of it. Tôi không thể tìm ra nguồn gốc của mini-phần mở rộng này ngay bây giờ (mặc dù nó đang làm chỉ là những gì bản vá mà không), nhưng những gì tôi nhận được là một phần mở rộng, BOM.py:

#!/usr/bin/env python 

from mercurial import hg, util 

import codecs 

boms = [ 
    codecs.BOM_UTF8, 
    codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE, 
    codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE 
    ] 

def binary(s): 
    if s: 
     for bom in boms: 
      if s.startswith(bom): 
       return False 
     return '\0' in s 
    return False 


def reposetup(ui, repo): 
    util.binary = binary 

này được nạp trong .hgrc (hoặc người dùng \ username \ mercurial.ini của bạn) như sau:

[extensions] 
bom = ~/.hgexts/BOM.py 

Lưu ý rằng đường dẫn sẽ khác nhau giữa Windows và Linux; trên bản sao Windows của tôi, tôi đặt đường dẫn là \...\whatever (trên đĩa USB nơi ký tự ổ đĩa có thể thay đổi). Thật không may đường dẫn tương đối được thực hiện tương đối so với thư mục làm việc hiện tại chứ không phải là gốc kho hoặc bất kỳ điều như vậy, nhưng nếu bạn đang lưu nó trên ổ C: bạn có thể đặt đường dẫn đầy đủ.

Trong Linux (môi trường phát triển chính của tôi), điều này hoạt động tốt; trong Command Prompt (mà tôi vẫn sử dụng thường xuyên), nó thường hoạt động tốt. Tôi chưa bao giờ thử nó trong PowerShell, nhưng tôi hy vọng nó sẽ tốt hơn Command Prompt trong sự hỗ trợ của nó cho các byte null tùy ý trong dòng lệnh.

Tôi không chắc chắn đây có phải là điều bạn muốn hay không; bằng cách bạn đã nói "nhị phân khác" Tôi nghi ngờ bạn có thể đã có hoặc đang làm hg diff -a đó là đạt được điều tương tự. Trong trường hợp đó, tất cả những gì tôi có thể nghĩ đến là viết một phần mở rộng khác có UTF-16LE và cố gắng giải mã nó thành UTF-8. Tôi không chắc chắn về cú pháp cho một phần mở rộng như vậy, nhưng tôi có thể thử điều đó.

Chỉnh sửa: hiện đã rà soát nguồn thủy ngân thông qua commands.py, cmdutil.py, patch.py ​​và mdiff.py, tôi thấy rằng các khác biệt nhị phân được thực hiện bằng mã hóa base85 (patch.b85diff) thay vì sự khác biệt bình thường. Tôi đã không nhận thức được điều đó, tôi nghĩ rằng nó chỉ buộc nó để diff nó. Trong trường hợp đó, có lẽ văn bản này có liên quan sau khi tất cả. Tôi đang chờ đợi một phản ứng để xem nếu nó được!

+1

Hãy coi chừng! Trong khi phần mở rộng này hoạt động cho việc phân biệt trên dòng lệnh, tôi đã gặp vấn đề với tham nhũng khi tạo các bản vá lỗi MQ thông qua 'qnew'. – jwd

+0

@jwd: đó có thể là lỗi trong mq. Không chắc chắn cách 'qnew' hoạt động. –

1

Nếu câu trả lời khác của tôi không làm những gì bạn muốn, tôi nghĩ rằng câu trả lời này có thể; mặc dù tôi chưa thử nghiệm nó trên Windows, nó hoạt động tốt trong Linux. Nó làm những gì có thể là một điều khó chịu, trong gói mercurial.mdiff.unidiff với một chức năng mới có thể chuyển đổi utf-16le thành utf-8. Điều này sẽ không ảnh hưởng đến hg st, nhưng sẽ ảnh hưởng đến hg diff. Một điểm yếu tiềm ẩn là BOM cũng sẽ được thay đổi từ UTF-16LE BOM thành UTF-8 BOM.

Dù sao, tôi nghĩ rằng nó có thể hữu ích cho bạn, vì vậy ở đây nó được.

mở rộng tập tin utf16decodediff.py:

import codecs 
from mercurial import mdiff 

unidiff = mdiff.unidiff 

def new_unidiff(a, ad, b, bd, fn1, fn2, r=None, opts=mdiff.defaultopts): 
    """ 
    A simple wrapper around mercurial.mdiff.unidiff which first decodes 
    UTF-16LE text. 
    """ 

    if a.startswith(codecs.BOM_UTF16_LE): 
     try: 
      # Gets reencoded as utf-8 to be a str rather than a unicode; some 
      # extensions may expect a str and may break if it's wrong. 
      a = a.decode('utf-16le').encode('utf-8') 
     except UnicodeDecodeError: 
      pass 

    if b.startswith(codecs.BOM_UTF16_LE): 
     try: 
      b = b.decode('utf-16le').encode('utf-8') 
     except UnicodeDecodeError: 
      pass 

    return unidiff(a, ad, b, bd, fn1, fn2, r, opts) 

mdiff.unidiff = new_unidiff 

Trong .hgrc:

[extensions] 
utf16decodediff = ~/.hgexts/utf16decodediff.py 

(. Hoặc đường dẫn tương đương)

+0

Thật không may, phương pháp này bị một vấn đề bộ nhớ: các tập tin được slurped lên (bởi mercurial, không phần mở rộng này) vì vậy nếu bộ nhớ là chặt chẽ, bạn có thể chạy ra ngoài. Nó đòi hỏi bạn phải thiết lập '--config diff.nobinary = True' (từ kinh nghiệm cá nhân tôi biết rằng điều này sẽ vít lên bản vá lỗi mq vì vậy tôi không khuyên bạn nên giữ nó cho phép vĩnh viễn) để đạt được wrapper. – bambams

+0

Tôi cũng khuyên bạn nên 'if isinstance (a, str):' và 'if isinstance (b, str)' vì khi thực hiện một khác biệt trong đó một phiên bản thiếu các tệp mà biến kia có thể là NoneType và làm cho phần mở rộng bị lỗi thuộc về thủy ngân – Scoopta

Các vấn đề liên quan