Переформатування та контроль версій


23

Форматування коду має значення. Навіть відступ має значення . А послідовність важливіша, ніж незначні покращення. Але проекти, як правило, не мають чіткого, повного, перевіреного та застосовуваного посібника щодо стилю з 1-го дня, і серйозні вдосконалення можуть надійти будь-якого дня. Можливо, ви знайдете це

SELECT id, name, address
FROM persons JOIN addresses ON persons.id = addresses.person_id;

може бути краще написано так, як / краще написано ніж

SELECT persons.id,
       persons.name,
       addresses.address
  FROM persons
  JOIN addresses ON persons.id = addresses.person_id;

під час роботи над додаванням більшої кількості стовпців до запиту. Можливо, це найскладніший з усіх чотирьох запитів у вашому коді, або тривіальний запит серед тисяч. Як би важкий не був перехід, ви вирішили, що він того вартий. Але як відстежувати зміни коду за основними змінами форматування? Ви можете просто відмовитись і сказати, "це ми починаємо знову" або ви можете переформатувати всі запити у всій історії сховищ.

Якщо ви використовуєте розподілену систему керування версіями, як-от Git, ви можете повернутися до першої фіксованої версії та переформатувати свій шлях звідти в поточний стан. Але це велика робота, і всі інші повинні були б призупинити роботу (або бути готовою до матері всіх злиття), поки вона триває. Чи є кращий спосіб змінити історію, який дає найкращі результати:

  • Один стиль у всіх комітах
  • Мінімальна робота злиття

?

Для уточнення, мова йде не про найкращі практики при запуску проекту, а про те, що слід робити, коли великий рефакторинг був визнаний хорошою річчю ™, але ви все ще хочете простежити історію? Ніколи не переписуйте історію чудово, якщо це єдиний спосіб забезпечити, щоб ваші версії завжди працювали однаково, але як щодо переваг розробника від чистого переписування? Особливо, якщо у вас є способи (тести, визначення синтаксису або ідентичний бінарний файл після компіляції), щоб переконатися, що переписана версія працює точно так само, як оригінал?


24
Чому ви хочете переписати історію? Це перемагає призначення контролю версій. Ви хочете переконатися, що додаток, яке ви відправили 3 місяці тому, відповідає ревізії xxxxxx без найменшого сумніву. Навіть тривіальне переформатування неприпустимо.
Саймон Берго

5
Мені подобається коментувати зобов’язання, що я роблю це з тегом "Reformat. Без функціональних змін"
Rig

3
На непов'язану тему це здається, що ви пропонували переписати історію Git, переформатувавши весь код. Не дайте людям уявлення, що переписування історії Git погано в 99,9% випадків. Переформатування не є .1% крайовим випадком.
Ендрю Т Фіннелл

4
У деяких мовах (я дивлюся на ВАС, Python) переформатування може змінити логічне функціонування коду. Вам потрібно буде мати змогу проаналізувати всі мови, що зберігаються у вашому веб-сайті, щоб безпечно відстежувати та ігнорувати переформатування.
Joris Timmermans

3
Реформати - це зміни коду, і їх слід здійснювати як такі.
Девід Кауден

Відповіді:


26

Робіть переформатування як окремі зобов'язання. Це мінімально буде втручатися в історію, і ви повинні мати можливість з першого погляду побачити, які зобов'язання лише переформатуються та які фактично змінюють код. Він може перекоситись git blameі подібне, але якщо це вказує на зобов'язання, що стосується лише переформатування, досить прямо вперед шукати попередню зміну до цього.


Я бачив проекти, що проходили під тиском у неділю, тому що один із розробників вважав це гарною ідеєю. Якщо ви збираєтеся це зробити, заздалегідь зрозумійте ризики та вирішіть, наскільки далеко ви збираєтесь піти з форматуванням. Я думаю, що mjfgates має правильну відповідь.
Джоннтрон

1
Здається, що у відповідної команди є більші проблеми, ніж із форматуванням коду. Але так, я не рекомендую робити це, якщо ви нічого не зробите. Якщо ви хочете змінити переформатування, я все-таки кажу, що краще виконувати їх як окремі коміти, ніж змішані з функціональними змінами.
Харальд

Так, багато проблем: PI просто хочуть попередити нових розробників, що це не просто, як це звучить. Інструменти масового переформатування є ризикованими (особливо, якщо ви створюєте його самостійно за допомогою регулярного вираження - принаймні, використовуйте AST), і якщо ви дбаєте про перегляд коду та відслідковування помилок, він справді може зіпсувати ваш процес. Особисто я пишу свій код, щоб він відповідав стилю кожного файлу, хоча я не проти перегляду коду, коли кілька функцій переформатуються. Багато розробників зациклюються на стилі коду і нехтують більшими проблемами, такими як архітектура, процес, інструментарій тощо
Johntron

У програмуванні нічого не так просто, як здається :)
Харальд

13

Не переписуйте історію VCS: це проти принципів VCS.

Не намагайтеся автоматизувати виправлення форматування: це лікування симптомів, а не справжня проблема (= розробники не дотримуються стандартів кодування).

Визначте стандарт кодування та найкращі практики форматування у загальному документі та домовтеся всіх розробників.

Ви згадуєте Git, що чудово, адже він розподілений. З DVCS дуже легко застосувати кращі практики через робочий процес воротаря . Провідники відхиляють пропозиції щодо злиття (= тягнути запити в Git), які не відповідають загальним інструкціям. І я маю на увазі відхилити жирними літерами, інакше кодер у порушенні не буде заважати виконувати правила і продовжувати повторювати ті самі помилки.

Ця методика добре працює для мене. Кодери хочуть, щоб їхня робота була об'єднана, тому після кількох помилок на початку вони починають дотримуватися правил.

Відповідно до виправлення існуючої бази коду ... Я рекомендую робити це поступово, можливо, модуль за модулем, або як це має сенс для вашого проекту. Тестуйте ретельно на кожному кроці. Це може здатися дурним, але помилки трапляються навіть при банальних змінах, таких як просто форматування, тому будьте готові до незначних ударів на дорозі.


1
Очевидно, оскільки автор чітко заявляє, що це в контексті проектів, які не починалися з "... чіткого, повного, перевіреного та застосованого керівництва стилем з першого дня". Він не може лікувати справжню проблему, бо це вже сталося. Я згоден з вами, хоча :)
Джонтрон

2
Відкинути означає, що між людиною і роботом відбудеться бійка. Був там. Рано чи пізно роботу потрібно буде відформатувати дійсно складний фрагмент коду, який не можна прочитати. Приклади: рядок Java насправді є оператором SQL, але робот цього не знає; пробіл перед закриттям паронів може нести інформацію про структуру коду для людини, але не для робота; Параметри функції розбиваються на кілька рядків самим безглуздим способом ...
18446744073709551615

9

Відповідь на ваше власне питання: "Ви цього не робите". Я не знаю жодного поточного інструменту SCM, який би міг відслідковувати зміни логіки від коду, відформатованого одним способом, через велику зміну форматування та через подальші зміни після форматування коду по-новому. І, ви знаєте це, втратити історію на фрагменті коду - це не добре.

Відповідно, я трохи заперечую ваше перше речення. Форматування коду не має значення , що багато. Досить приємно, але це не те, для чого ми тут. Я розумію, як і хто-небудь, що потрапляння в чийсь старий пекельний дивний код варіанту K&R з двома пробілами відступає (1), але ... форматування насправді не є перешкодою для розуміння того, що відбувається, якщо це не щось виняткове патологічні. І в цьому випадку у вас все одно виникнуть проблеми зі зміною коду, і це не повинно турбувати.

Тому вносити зміни до встановленого коду СТРАТИНО для його переформатування не варто. Зміна назв змінних, розбиття довгих функцій, все те добре рефакторинг, що змінює вміст, так, але не ПОВЕРНЕНО переформатування.

1) - Колись я деякий час був власником переглядача буфера обміну Windows. Вся справа була одна, 150 к, модуль С. Я знайшов місце, де різні люди використовували, я думаю, п'ять різних стилів брекетів в межах тридцяти рядків один від одного. Але цей розділ речей працював. Я носив роздруківку цього фрагмента коду протягом десяти років, але я не ткнув його, тому що ця історія мала значення, і цей код був щонайменше у трьох вихідних деревах (Windows 3.x, NT, майбутня 95), які всі жили в різних будівлях.


У минулому, використовуючи hg, я виявив, що злиття по частинах є неоціненним інструментом для подолання складних великих злиття ре-факторів . Як правило, я б зробив об'єднання комітетів перед великим ре-фактором, потім злиття самого великого ре-фактору, а потім, нарешті, об'єднання комітетів після рефактора. Кожен з цих трьох злиттів самих по собі є набагато простіше , ніж намагатися розплутати безлад , що результати робити все злиття на одному диханні.
Марк Бут

Я цілком погоджуюся! Крім того, я бачив, як багато розробників перебирають за борт (у тому числі і молодша версія) щодо переформатування та стилю коду, і вони виявляють дефекти. Тут відсутня кома / крапка з комою, декларації змінних переміщуються у верхню частину функцій, а для-циклів змінено на "для-кожного" - вони можуть вводити непомітні помилки. Щоб безпечно зробити ці зміни, потрібна обманлива кількість вмінь.
Джоннтрон

4

Але як відстежувати зміни коду за основними змінами форматування?

Форматування змін є зміни коду; поводьтеся з ними так, як і до будь-яких інших змін у вашому коді. Кожен, хто працював над значним проектом, напевно, побачив помилки та інші проблеми, які були створені, коли хтось вирішив "просто" переформатувати якийсь код.

Але це велика робота, і всі інші повинні були б призупинити роботу (або бути готовою до матері всіх злиття), поки вона триває.

Чому ви повинні переформатувати все одночасно? Особливо, якщо переформатування не змінює значення коду, ви повинні мати можливість переформатувати файли окремо та перевірити їх у процесі роботи. Краще, дозвольте всім у вашій команді домовитись про стиль (інакше все-таки немає сенсу в переформатуванні) і дозвольте всім подбати про переформатування в процесі своєї іншої роботи. Через деякий час ви покриєте більшу частину коду, не порушуючи решту проекту.


1

Я бачив для цього два підходи, які я бачив.

1. Код переформатування на гачок фіксації

Хоча це спочатку зачіска для зміни коду після їх подання, якщо процедура переформатування (наприклад, astyle ) не зашкодить коду, це безпечна робота. З часом вся команда оцінить, що весь код зрештою виглядає однаково. Зрозуміло, наявність всеосяжних одиниць / автоматизованих тестів забезпечить, щоб нічого не зламалося.

2. Одноразове переформатування всього коду

На моєму досвіді це більш небезпечно і ускладнює відстеження проблем на великому рівні, але це можливо. Після цього важливо виконати всі тести. Для стилю кодування більшість відмінностей обертається навколо використання пробілів - відступу або нових рядків. Достойний інструмент злиття повинен мати можливість ігнорувати всі відмінності пробілів, тому це допоможе злиттям.


1
Не вдалося б вибрати один варіант, коли ввімкнути пульсацію по всій базі коду швидко, що призведе до того ж великого удару від зміни кожного файлу?
Увійти

@Sign: Точно моя думка - Коли гачок фіксації зміниться, ваша історія може погіршитися в щось майже марне. Форматування, яке не змінює функціональність, не повинно бути зобов'язанням, його слід пересаджувати протягом історії коду.
l0b0

1
Якщо IDE підтримує його, то є також 3), майте автоформат IDE при збереженні. Тоді просто використовуйте однакові налаштування скрізь - це найпростіше, якщо ви використовуєте за замовчуванням IDE.

Я зробив обидва ці підходи. Перший підхід дуже нав'язливий, оскільки відбудеться ціла кількість змін кожного разу, коли новий файл буде введено вперше. Другий підхід для команди кращий, як швидке зривання бандаїда.
Друська
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.