.NET Разработчик
6.52K subscribers
442 photos
3 videos
14 files
2.12K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День семьсот девяносто седьмой. #Шпаргалка
20 Команд Git, Которые Надо Знать
Git был выпущен в 2005 году. Несмотря на то, что сейчас появилось много программ с графическим интерфейсом для управления репозиторием, труЪ программеры используют консоль. Поэтому ловите 20 наиболее полезных команд Git, которые понадобятся любому разработчику. Подробности о работе Git см. начиная с этого поста.

1. Вывести конфигурацию
git config -l
Эта команда отображает список информации о вашей конфигурации git, включая имя пользователя, адрес электронной почты, редактор кода по умолчанию и т.д.

2. Изменить ваше имя пользователя
git config --global user.name "<ваше имя>"

3. Изменить ваш email
git config --global user.email "test@email.com"

4. Создать репозиторий
git init
Эта команда инициализирует репозиторий в текущей папке.

5. Добавить файл в staging
git add my_file

6. Добавить все файлы в staging
git add .

7. Проверить статус
git status
Эта команда покажет статус текущего репозитория, включая текущую ветку, и файлы как в staging, так и не добавленные туда.

8. Commit
git commit
Эта команда создаст коммит. В этом варианте откроется текстовый редактор, куда вам нужно будет записать сообщение коммита.

9. Commit с сообщением
git commit -m "Ваше сообщение"

10. Просмотр истории
git log

11. Список веток
git branch

12. Создание ветки
git branch my_branch
Заметьте, что Git не переключится на эту ветку автоматом. Для этого см. пункт 14.

13. Удаление ветки
git branch -d my_branch
Обратите внимание на флаг -d.

14. Переключение между ветками
git checkout my_branch

15. Создание ветки и переключение на неё
Пункты 12 и 14 можно объединить в одну команду:
git checkout -b branch_name

16. Добавление удалённого репозитория
git add remote https://repo_url

17. Публикация в удалённый репозиторий
git push

18. Обновление из удалённого репозитория
git pull

19. Временное сохранение изменений
git stash
Эта команда временно сохранит неподтверждённые изменения и вернёт ваш репозиторий в состояние последнего коммита.

20. Получение временно сохранённых изменений
git stash pop
Эта команда применит сохранённые ранее изменения обратно к вашему репозиторию.

Источник: https://www.c-sharpcorner.com/article/20-git-commands-you-should-know/
День 1191.
Подборка тегов, используемых в постах на канале, чтобы облегчить поиск. Не могу гарантировать, что все 1190 постов идеально и корректно помечены тегами, но всё-таки, эта подборка должна помочь.

Общие
Эти посты на совершенно разные темы, помечены этими тегами только с целью различать общую направленность поста.

#ЗаметкиНаПолях – технические посты. Краткие описания теории, особенности языка C# и платформы .NET, примеры кода, и т.п.

#Шпаргалка - примеры кода, команды для утилит и т.п.

#Юмор – шутки, комиксы и просто весёлые тексты или ссылки на видео.

#Оффтоп – всё прочее.


Специализированные
Эти теги более тематические, выделяют основную тему поста.

#Карьера – советы по повышению продуктивности, карьерному росту, прохождению собеседований и т.п.

#Книги – обзоры книг, которые (чаще всего) я лично прочитал, либо ещё нет, но советую прочитать.

#Курсы – обзоры и ссылки на онлайн курсы.

#МоиИнструменты – различные программы, утилиты и расширения IDE, которые я использую в работе.

#ЧтоНовенького – новости из мира .NET.


Узкоспециализированные
Эти теги относятся к определённой узкой теме.

#AsyncTips – серия постов из книги Стивена Клири “Конкурентность в C#”
#AsyncAwaitFAQ – серия постов “Самые Частые Ошибки при Работе с async/await.”

#BestPractices – советы по лучшим практикам, паттернам разработки.

#DesignPatterns – всё о паттернах проектирования, SOLID, IDEALS и т.п.

#DotNetAZ – серия постов с описанием терминов из мира .NET.

#GC – серия постов “Топ Вопросов о Памяти в .NET.” от Конрада Кокосы.

#MoreEffectiveCSharp – серия постов из книги Билла Вагнера “More Effective C#”.

#Testing – всё о тестировании кода.

#TipsAndTricks – советы и трюки, в основном по функционалу Visual Studio.

#Quiz - опросы в виде викторины.

#97Вещей – серия постов из книги “97 Вещей, Которые Должен Знать Каждый Программист”.

#ВопросыНаСобеседовании – тег говорит сам за себя, самые часто задаваемые вопросы на собеседовании по C#, ASP.NET и .NET.
#ЗадачиНаСобеседовании – похоже на вопросы, но здесь больше приводятся практические задачи. Чаще всего это 2 поста: собственно задача и ответ с разбором.

#КакСтатьСеньором – серия постов «Как Стать Сеньором» с советами о продвижении по карьерной лестнице.

Помимо этого, можно просто воспользоваться поиском по постам и попробовать найти то, что вам нужно.
1👍60👎1
День 1837. #Шпаргалка
Примеры Кода для Повседневных Задач
В этой серии представлю вам коллекцию фрагментов кода C#, охватывающих широкий спектр сценариев, с которыми вы можете столкнуться при разработке ПО.

I. Словари
Словари - гибкая структура данных для соединения пар элементов.

1. Объединение двух словарей
Обычная операция при работе со структурами данных. Объединение словарей может оказаться непростой задачей, особенно при наличии повторяющихся ключей. Что делать при этом, будет зависеть от ваших потребностей. Вот несколько примеров:
var dict1 = new Dictionary<string, string> { 
{ "Superman", "Flight" }
};
var dict2 = new Dictionary<string, string> {
{ "Batman", "Gadgets" }
};

// LINQ
var merged = dict1
.Concat(dict2)
.ToDictionary(x => x.Key, x => x.Value);

// Цикл foreach
foreach (var item in dict2)
dict1[item.Key] = item.Value;

// Метод расширения Union
var merged2 = dict1
.Union(dict2)
.ToDictionary(x => x.Key, x => x.Value);


2. Инвертирование
Что, если вам нужно поменять местами ключи и значения словаря? Операция может осложниться, если у вас неуникальные или нехешируемые значения:
var heroes = new Dictionary<string, string>
{
{ "Flash", "Super Speed" },
{ "Green Lantern", "Power Ring" },
{ "Aquaman", "Atlantean Strength" }
};

// LINQ
var inverted = heroes
.ToDictionary(x => x.Value, x => x.Key);

// Цикл foreach
var inverted2 = new Dictionary<string, string>();
foreach (var item in heroes)
inverted2[item.Value] = item.Key;


3. Обратный поиск
Обратный поиск (найти ключ для данного значения) может быть полезен, когда словарь слишком велик для инвертирования:
var dimensions = new Dictionary<string, int>
{
{ "length", 10 },
{ "width", 20 },
{ "height", 30 }
};

int val = 20;

// "В лоб" – первый ключ
foreach (var d in dimensions)
{
if (d.Value == val)
{
Console.WriteLine($"{d.Key}: {d.Value}");
break;
}
}

// "В лоб" – все ключи
foreach (var d in dimensions)
{
if (d.Value == val)
Console.WriteLine($"{d.Key}: {d.Value}");
}

// LINQ – первый ключ
var key = dimensions
.FirstOrDefault(x => x.Value == val)
.Key;

// LINQ – все ключи
var keys = dimensions
.Where(x => x.Value == val)
.Select(x => x.Key);

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

Источник: https://medium.com/bytehide/100-csharp-code-snippets-for-everyday-problems-e913c786dec9
👍17👎3
День 1844. #Шпаргалка
Примеры Кода для Повседневных Задач

В этой серии представлю вам коллекцию фрагментов кода C#, охватывающих широкий спектр сценариев, с которыми вы можете столкнуться при разработке ПО.

II. Списки. Начало
Среди различных структур данных списки выделяются как наиболее распространённые. В C# список представляет собой «динамический массив». Мы можем добавлять и удалять элементы, не беспокоясь о лежащей в основе реализации, что делает списки интуитивно понятными в обращении.

1. Добавление элемента
C# предлагает множество способов добавления элементов в список:
// Статическая инициализация
var list = new List<int> {1, 2};
// Начиная с C# 12
List<int> list2 = [2, 3];

// Добавление - Add
list.Add(3); // [1, 2, 3]
// Добавление списка - AddRange
list.AddRange(new List<int> {4, 5});
// [1, 2, 3, 4, 5]

// Начиная с C# 12 – оператор расширения
List<int> list3 = [..list2, 4];
// [2, 3, 4]

// Вставка - Insert
list2.Insert(0, 1);
// [1, 2, 3]

// Вставка списка - InsertRange
list2.InsertRange(list2.Count, new List<int> {4, 5});
// [1, 2, 3, 4, 5]

См. подробнее про оператор расширения.

2. Получение последнего элемента
C# предлагает несколько интересных альтернатив:
List<string> list = ["red", "blue", "green"];

// Стандартно через Count
var last = list[list.Count - 1];
// LINQ
last = list.Last();
// индексатор
last = list[^1];


3. Проверка пуст ли список
И снова, есть несколько вариантов (на всякий случай, добавим проверку на null):
// Метод Count
if ((list?.Count ?? 0) == 0)
{
// список пуст
}
// LINQ
if (list?.Any() != true)
{
// список пуст
}


4. Клонирование списка
При работе со ссылочными типами всегда следует помнить, что простое присваивание их другой переменной копирует только ссылку:
List<int> list = [1, 2, 3];
// LINQ
var duplicate = list.ToList();
// Конструктор
duplicate = new List<int>(list);
// Начиная с C# 12 – оператор расширения
duplicate = [..list];


Окончание следует…

Источник:
https://medium.com/bytehide/100-csharp-code-snippets-for-everyday-problems-e913c786dec9
👍21
День 1845. #Шпаргалка
Примеры Кода для Повседневных Задач

В этой серии представлю вам коллекцию фрагментов кода C#, охватывающих широкий спектр сценариев, с которыми вы можете столкнуться при разработке ПО.

II. Списки. Окончание
Начало

5. Генераторы списков
List comprehension — мощная функция Python, название которой сложно перевести на русский. Назовём это просто генерацией списков. В C# нет прямого эквивалента, но можно добиться аналогичной функциональности, используя LINQ:
List<int> list = [1, -2, 3];

// Преобразование
var squares = list
.Select(i => i*i).ToList();

// Фильтрация
var positive = list
.Where(i => i > 0).ToList();

// Все возможные пары
var list2 = new List<int> { 4, 5, 6 };
var pairs = list
.SelectMany(a => list2, (a, b) => (a, b))
.ToList();

И т.п.

6. Попарная обработка элементов двух списков
Представьте, что у вас есть два списка, и ваша цель — объединить их в один путём, например, попарного суммирования элементов:
List<int> list = [1, 2, 3, 4, 5, 6];
List<int> list2 = [4, 8, 15, 16, 23, 42];

// «В лоб» в цикле
var sum = new List<int>();
for (int i = 0; i < list.Count; i++)
sum.Add(list[i] + list2[i]);

// LINQ метод Zip
sum = list
.Zip(list2, (x, y) => x + y).ToList();

Замечание: в отличие от примера «в лоб», метод Zip корректно обрабатывает ситуации, когда списки разной длины. Длина результирующего списка будет равна длине меньшего из списков.

7. Сортировка
Сортировка строк (или сложных объектов) имеет свои особенности, в которые мы не будем здесь углубляться. Отметим, что у нас есть несколько вариантов:
List<string> list = ["leaf", "cherry", "Fish"];

// «На месте»
list.Sort();
// Без учёта регистра
list.Sort(StringComparer.OrdinalIgnoreCase);

// в новый список
var sorted = list
.OrderBy(x => x, StringComparer.OrdinalIgnoreCase)
.ToList();

Если требуется сортировка объектов по какому-либо свойству, метод Sort также может принимать компаратор или лямбда-выражение для сравнения объектов между собой. См. подробнее в конце этого поста.

Источник: https://medium.com/bytehide/100-csharp-code-snippets-for-everyday-problems-e913c786dec9
👍12
День 1851. #Шпаргалка
Примеры Кода для Повседневных Задач
В этой серии представлю вам коллекцию фрагментов кода C#, охватывающих широкий спектр сценариев, с которыми вы можете столкнуться при разработке ПО.


III. Операции с файлами
Операции с файлами являются общим требованием во многих задачах. В этом разделе мы рассмотрим, как работать с файлами и каталогами в C#, используя пространство имён System.IO.

1. Чтение текстового файла
Чтобы прочитать текстовый файл в C#, вы можете использовать класс File и его метод ReadAllText():
var path = "example.txt";
var content = File.ReadAllText(path);
Console.WriteLine(content);


2. Запись текстового файла
Чтобы записать текстовый файл, можно использовать метод WriteAllText() класса File:
var path = "output.txt";
var content = "Hello, World!";
File.WriteAllText(path, content);


3. Дозапись текста в файл
Чтобы добавить текст в текущий файл, можно использовать метод AppendAllText():
var path = "log.txt";
var logEntry = "New log entry";
File.AppendAllText(path, logEntry);


4. Чтение файла построчно
Для чтения файла построчно подойдёт метод ReadLines():
var path = "example.txt";
foreach (var line in File.ReadLines(path))
Console.WriteLine(line);


5. Создание/удаление папки
Для создания/удаления папки используйте соответственно методы CreateDirectory() и Delete() класса Directory:
var path = "new_directory";
Directory.CreateDirectory(path);
Directory.Delete(path, true);

Второй параметр метода Delete указывает, надо ли удалять всё содержимое папки.

6. Проверка существования
Чтобы проверить существование файла или папки, используйте метод Exists() класса File или Directory соответственно:
var fPath = "example.txt";
var dPath = "directory";

var fileExists = File.Exists(fPath);
var dirExists = Directory.Exists(dPath);


7. Список файлов в папке
Используйте метод GetFiles() класса Directory:
var path = " directory";
var files = Directory.GetFiles(path);

foreach (var f in files)
Console.WriteLine(f);


8. Копия/перемещение файла
Используйте соответственно методы Copy() или Move() класса File:
var source = "example.txt";
var copy = "copy_example.txt";
var moved = "moved_example.txt";

File.Copy(source, copy);

File.Move(source, moved);


Источник: https://medium.com/bytehide/100-csharp-code-snippets-for-everyday-problems-e913c786dec9
👍17👎1
День 1858. #Шпаргалка
Примеры Кода для Повседневных Задач

В этой серии представлю вам коллекцию фрагментов кода C#, охватывающих широкий спектр сценариев, с которыми вы можете столкнуться при разработке ПО.

IV. Потоки
Многопоточная обработка — важный аспект параллельного программирования на C#. Рассмотрим, как работать с потоками, используя пространство имен System.Threading.

1. Создание нового потока
Чтобы создать новый поток в C#, вы можете использовать класс Thread:
using System.Threading;

void PrintNumbers()
{
for (int i = 1; i <= 5; i++)
Console.WriteLine(i);
}

var thread = new Thread(PrintNumbers);


2. Операции над потоком
- Запуск
thread.Start();

- Слияние (ожидание завершения потока)
thread.Join();

- Приостановка (текущий поток)
Thread.Sleep(1000); // пауза на 1 секунду

См. подробнее о потоках

3. Использование пула потоков
Для работы с пулом потоков используется класс ThreadPool:
using System.Threading;

ThreadPool.QueueUserWorkItem(PrintNumbers);

См. подробнее о пуле потоков

V. Задачи
1. Создание новой задачи

Для создания и запуска задачи используется класс Task:
using System.Threading.Tasks;

Task.Run(PrintNumbers);

См. подробнее о задачах

2. Ожидание задачи
var task = Task.Run(PrintNumbers);
task.Wait();


3. Отмена задачи
Для отмены задачи в C# используется класс CancellationTokenSource, создающий токен отмены. А для собственно отмены – метод токена Cancel():
using System.Threading;
using System.Threading.Tasks;

var cts = new CancellationTokenSource();
Task.Run(() => PrintNumbers(), cts.Token);
cts.Cancel();

См. подробнее «Скоординированная отмена»

Источник: https://medium.com/bytehide/100-csharp-code-snippets-for-everyday-problems-e913c786dec9
👍14
День 1868. #Шпаргалка #Git
Популярные Настройки Git Config. Начало
Джулия Эванс спросила у коллег-программистов мнения о самых популярных и полезных настройках Git, которые они используют. Вот такой список получился.

Описание всех настроек можно найти в документации Git.

1. pull.ff only или pull.rebase true
Эти две были самыми популярными. Обе они преследуют схожие цели: избежать случайного создания коммита слияния при запуске git pull на ветке, где восходящая ветвь расходится.
- pull.rebase true эквивалентен запуску git pull --rebase каждый раз,
- pull.ff only эквивалентен запуску git pull --ff-only каждый раз.
Скорее всего, нет смысла устанавливать обе одновременно, поскольку --ff-only переопределяет --rebase.

2. merge.conflictstyle zdiff3
Делаем конфликты слияний более читабельными!
По умолчанию в git конфликты слияния выглядят так:
<<<<<<< HEAD
def parse(input):
return input.split("\n")
=======
def parse(text):
return text.split("\n\n")
>>>>>>> somebranch

Вам предлагается решить, что лучше: input.split("\n") или text.split("\n\n"). Но как? Что делать, если вы не помните, нужно \n или \n\n?
Вот как выглядит тот же конфликт слияния с merge.conflictstyle diff3:
<<<<<<< HEAD
def parse(input):
return input.split("\n")
||||||| base
def parse(input):
return input.split("\n\n")
=======
def parse(text):
return text.split("\n\n")
>>>>>>> somebranch

Здесь содержится дополнительная информация: теперь исходная версия кода находится посередине! Итак, мы видим:
- одна сторона изменила \n\n на \n,
- другая сторона переименовала input в text.
Поэтому, по-видимому, правильным решением конфликта слияния является return text.split("\n"), поскольку он объединяет изменения с обеих сторон.
zdiff3 — это тот же diff3, но он лучше выносит любые общие строки в начале или конце за пределы зоны конфликта. То есть, если обе стороны сделали изменения, которые имеют общие строки в начале или в конце, то они будут корректно слиты и не будут входить в зону конфликта.

3. rebase.autosquash true
Цель autosquash — упростить модификацию старых коммитов. Допустим, у вас есть коммит с исправлением другого коммита (3 коммита назад), который вы хотели бы объединить с ним. Вы фиксируете новый коммит с помощью git commit --fixup OLD_COMMIT_ID, что даёт новому коммиту сообщение «fixup! …».
Теперь, когда вы запускаете git rebase --autosquash main, он автоматически объединяет все коммиты-исправления (fixup!) со своими целями.
rebase.autosquash true означает, что --autosquash всегда автоматически передаётся в git rebase.

4. rebase.autostash true
Это автоматически запускает git stash перед git rebase и git stash pop после. По сути, он передаёт --autostash в git rebase. Это означает, что вы можете запустить rebase на «грязном» рабочем дереве. Однако будьте осторожны: применение изменений из stash после успешного перебазирования может привести к нетривиальным конфликтам. Хотя, похоже, это не очень часто встречается у людей, поскольку этот вариант конфигурации кажется действительно популярным.

Продолжение следует…

Источник:
https://jvns.ca/blog/2024/02/16/popular-git-config-options/
👍13
День 1869. #Шпаргалка #Git
Популярные Настройки Git Config. Продолжение

Начало

5. push.default simple и push.default current
Параметры push.default сообщают git push автоматически отправлять текущую ветку в удалённую ветку с тем же именем.
- push.default simple — значение по умолчанию в Git. Это работает только в том случае, если ваша ветка уже отслеживает удалённую ветку.
- push.default current - аналогична, но она всегда передаёт локальную ветку в удалённую ветку с тем же именем.
current кажется хорошей настройкой, если вы уверены, что никогда случайно не создадите локальную ветку с тем же именем, что и несвязанная удалённая ветка. У многих людей есть соглашения об именах веток (например, julia/my-change), которые делают конфликты такого рода маловероятными, либо у них просто мало сотрудников, поэтому конфликтов имён ветвей, вероятно, не происходит.

6. init.defaultBranch main
Создавать ветку main вместо ветки master при создании нового репозитория.

7. commit.verbose true
Добавит все различия коммита в текстовый редактор, где вы пишете сообщение о коммите, чтобы помочь вам запомнить, что вы делали.

8. rerere.enabled true
Позволяет использовать функцию rerere (reuse recovered resolution - повторно использовать восстановленное разрешение), которая запоминает, как вы разрешали конфликты слияния во время git rebase, и автоматически разрешает конфликты за вас, когда это возможно.

9. help.autocorrect 10
Если git обнаружит опечатки и сможет определить ровно одну действительную команду, аналогичную ошибке, он попытается предложить правильную команду или даже автоматически запустить предложение. Возможные значения:
- 0 (по умолчанию) - показать предложенную команду.
- положительное число - запустить предложенную команду через указанные децисекунды (0,1 секунды).
- "immediate" - немедленно запустить предложенную команду.
- "prompt" - показать предложение и запросить подтверждение для запуска команды.
- "never" - не запускать и не показывать предлагаемые команды.

10. core.pager delta
«Пейджер» — это то, что git использует для отображения результатов git diff, git log, git show и т. д.
delta – это модный инструмент для просмотра различий с подсветкой синтаксиса.

11. diff.algorithm histogram
Алгоритм сравнения Git по умолчанию часто плохо справляется с переупорядочением функций. Например:
-.header {
+.footer {
margin: 0;
}

-.footer {
+.header {
margin: 0;
+ color: green;
}

Это сильно путает. Но с diff.algorithm histogram всё становится гораздо понятнее:
-.header {
- margin: 0;
-}
-
.footer {
margin: 0;
}

+.header {
+ margin: 0;
+ color: green;
+}

Ещё один популярный вариант - patience.

12. core.excludesFile – глобальный .gitignore
core.excludesFile = ~/.gitignore позволяет установить глобальный файл gitignore, который применяется ко всем репозиториям, для таких вещей, как .idea или .vs, которые вы никогда не хотите коммитить в какой-либо репозиторий. По умолчанию это ~/.config/git/ignore.

Окончание следует…

Источник:
https://jvns.ca/blog/2024/02/16/popular-git-config-options/
👍12
День 1870. #Шпаргалка #Git
Популярные Настройки Git Config. Окончание

Начало
Продолжение

13. includeIf: отдельные конфигурации git для личного и рабочего
Многие используют это для настройки разных email для личных и рабочих репозиториев. Вы можете настроить это примерно так:
[includeIf "gitdir:~/code/<work>/"]
path = "~/code/<work>/.gitconfig"


14. url."git@github.com:".insteadOf 'https://github.com/'
Если вы часто случайно клонируете HTTP-версию репозитория вместо SSH-версии, а затем приходится вручную заходить в ~/.git/config и редактировать удалённый URL, это заменит https://github.com в удалённых репозиториях на git@github.com:
[url "git@github.com:"]
insteadOf = https://github.com/

Кто-то вместо этого использует pushInsteadOf для замены только в git push, потому что не хочет разблокировать свой SSH-ключ при извлечении из общедоступного репозитория.

15. fsckobjects
Проверяет получаемые/отправляемые объекты. Если будет обнаружено повреждение или ссылка на несуществующий объект, операция прервётся:
transfer.fsckobjects = true
fetch.fsckobjects = true
receive.fsckObjects = true

16. Остальное
- blame.ignoreRevsFile .git-blame-ignore-revs
Позволяет указать файл с коммитами, который следует игнорировать во время git blame, чтобы гигантские переименования не мешал.
- branch.sort -committerdate
Заставит git branch сортировать ветки по последнему использованию, а не по алфавиту, чтобы упростить поиск ветвей. tag.sort taggerdate аналогично для тегов.
- color.ui false
Отключает подстветку.
- core.autocrlf false
В Windows для работы совместно с коллегами на Unix.
- core.editor emacs
Использовать emacs (или другой редактор) для сообщений коммита.
- diff.tool difftastic
Использовать difftastic (или другой редактор) для отображения различий.
- merge.tool meld
Использовать meld (или другой редактор) для разрешения конфликтов слияния.
- fetch.prune true и fetch.prunetags
Автоматически удалит локальные ветки и теги, которых больше нет в удалённом репозитории.
- gpg.format ssh
Позволит подписывать коммиты ключами SSH.
- log.date iso
Отобразит даты как 2024-03-14 15:54:51 вместо Thu Mar 14 15:54:51 2024
- merge.keepbackup false
Чтобы избавиться от файлов .orig, которые git создаёт при слиянии конфликтов.
- push.followtags true
Добавит новые теги вместе с добавляемыми коммитами.
- rebase.missingCommitsCheck error
Не позволит удалять коммиты во время rebase.

Источник: https://jvns.ca/blog/2024/02/16/popular-git-config-options/
👍7
День 1918. #Шпаргалка
Шпаргалка по Форматированию Дат
Структура System.DateTime, доступная только для чтения, определённая в библиотеке базовых классов .NET (BCL), является ключом к обработке дат и времени в C#. Отформатировать дату и время для вывода можно, указав формат в методе ToString("…"). Например:
csharp 
Console.WriteLine(
DateTime.Now.ToString("ddd, dd MMM yyyy h:mm"));

Выведет:
Wed 01 May 2024 8:01

Ниже приведены краткие пояснения некоторых часто используемых спецификаторов формата:
d – день месяца от 1 до 31.
dd – день месяца от 01 до 31.
ddd - аббревиатура дня недели (Mon, Tue, …).
dddd - полный день недели (Monday, Tuesday, …).
h - 12-часовой формат часов.
hh - 12-часовой формат часов с ведущим 0.
H - 24-часовой формат часов.
HH - 24-часовой формат часов с ведущим 0.
m - минуты.
mm - минуты с ведущим 0.
M - номер месяца.
MM - номер месяца с ведущим 0.
MMM - краткое имя месяца (Dec).
MMMM - полное имя месяца (December).
s - секунды.
ss - секунды с ведущим 0.
f - десятые доли секунды.
ff - сотые доли секунды.
t - краткое AM/PM (A или P).
tt - AM/PM (AM или PM).
yyyy - год.
z - часов от UTC (+3).
zz - часов от UTC с ведущим 0 (+03).
zzz - часов и минут от UTC (+03:00).
K - аналогично zzz, но адаптирует вывод в зависимости от типа времени (местное, UTC или не указано), поэтому может не вывести ничего.

Символы FHKMdfghmstyz%:/\"' зарезервированы в строке формата даты и времени. Они интерпретируются как символы форматирования, за исключением случаев, когда используются внутри одинарных или двойных кавычек, либо экранированы \. Все остальные символы последовательно интерпретируются как символьные литералы и остаются неизменными при выводе во время операции форматирования.

Также есть несколько стандартных спецификаторов формата, каждый из которых представлен одной буквой
* - зависит от культуры, ниже примеры для культуры "en-US":
"d" - короткая дата* (05/01/2024)
"D" - полная дата* (Wednesday, May 01, 2024)
"f" - полная дата, короткое время* (Wednesday, May 01, 2024 8:01 AM)
"F" - полная дата, полное время* (Wednesday, May 01, 2024 8:01:03 AM)
"g" - короткая дата, короткое время* (05/01/2024 8:01 AM)
"G" - короткая дата, полное время* (05/01/2024 8:01:03 AM)
"m" или "M" - день/месяц* (May 1)
"o" или "O" - полные дата/время по ISO 8601 (2024-05-01T08:01:03.7300000+04:00)
"s" - сортируемые дата/время по ISO 8601 (2024-05-01T08:03:01)
"r" или "R" - дата/время по RFC1123 (Wed, 01 May 2024 08:01:03 GMT)
"t" - короткое время* (8:01 AM)
"T" - длинное время* (8:01:03 AM)
"u" - универсальный сортируемый формат даты/времени (2024-05-01 05:01:03Z)
"U" - универсальный полный формат даты/времени (Wednesday, May 01, 2024 5:01:03 AM)
"y" или "Y" - месяц/год* (May 2024)
Любой другой символ приведёт к исключению FormatException во время выполнения.

Источник: https://blog.ndepend.com/csharp-datetime-format/
👍34