С точки зрения сетевого стэка тут про 4 уровня: L4/L3 (TCP/IP), L6 (TLS) и L7 (HTTP). Входящие на сервер запросы от клиента можно различать по каждому уровню отдельно.
Между 1000 разных клиентов IP адрес может быть общим, но исходящие TCP порты всегда будут разными. И если провайдер держит TCP соединение (а он по идее должен), то комбинация IP-port (socket) не меняются пока клиент (или сервер) явно не закроют соединение или клиент потеряет связь.
TLS handshake будет различаться по набору клиентских алгоритмов, но как измерение для fingerprint оно не очень уникальное.
HTTP уровню в целом без разницы что происходит на нижних уровнях даже если они делают TCP reconnect. И тут сессия клиента после логина сохраняется с помощью http header (уникальный cookie -> user id). Без логина тоже можно присвоить уникальный cookie. Остальные http headers могут быть разными, но не являются уникальным fingerprint.
Если парсер выдает себя за обычный браузер, то его блокировка уже нетривиальная задача, но есть разные методы борьбы с ними.
И я также согласен, что форс-пуш лучше избегать. Можно изменить этот подход без потери истории, не создавая rebase, и не делая форс-пуш.
# уходим в detached state
git switch --detach origin/main
# мержим ветку в detached HEAD
git merge -n feature
# выходим из мерджа, решаем конфликты, добавляем файлы
git merge --quit
git add -A
# создаем временный коммит чтобы зафиксировать результат как HEAD
git commit -m "Temp commit"
# самый главный трюк: создаем merge commit используя HEAD с двумя парентами, полчаем его хэш и
# сразу переносим ветку на этот новый коммит (по сути fast-forward)
git switch -C feature $(git commit-tree HEAD^{tree} -p feature -p origin/main -m "Merged branch 'main' into 'feature'")
# обычный пуш без форса
git push origin feature
В общем я использовал тот же прием, про который писал на Хабре тут и тут.
Когда 3 года назад произошел большой взрыв технологии LLM, компьютеры Apple оказались единственными способными на быстрый inference моделей малого и среднего размера за счёт unified memory для CPU и GPU с колоссальной пропускной способностью. К сожалению, до сих пор нет нормальной альтернативы, а Mac Studio с большим объемом памяти просто убрали из продажи. Компания Apple опять на коне. Ещё бы была поддержка CUDA, то их рабочие станции стали бы золотым стандартом для исследователей и разработчиков в сфере AI.
Линус Торвальдс много раз объяснял почему Linux на C и в нём никогда не будет C++. И одна из причин было то, что он не хочет, чтобы код в его проекте писали C++ программисты. При этом Rust был им допущен и уже есть в исходниках Linux.
Каждый коммит в git описывает состояние проекта целиком и полностью, а видимый diff всегда вычисляется динамически. Коммит это дерево проекта (tree) + метаданные, более подробно в моей статье тут.
List<Integer> list = new ArrayList<>();
Deque<Integer> queue = new ArrayDeque<>();
Set<Integer> set = new HashSet<>();
Map<Integer, String> map = new HashMap<>();
NavigableSet<Integer> set = new TreeSet<>();
NavigableMap<Integer, String> map = new TreeMap<>();
Субъективно, Waymo ездит очень аккуратно, по всем правилам, но как робот, теряется в нетипичных ситуациях. Я думаю, что аварийность значительно меньше, чем у Uber.
Если разработчик лично предпочитает merge, но на текущем проекте всем нужно делать rebase, то в таком случае данный метод это очень хороший компромисс.
И я согласен, что rebase требует большей квалификации и понимания, чем merge. И что rebase противоречит оригинальной идеологии git, что все коммиты должны быть иммутабельны.
Допустим, общая ветка (upstream) это develop, есть три варианта насколько строго требовать корректность коммитов в репозитории на сервере:
develop должен быть корректным в любой момент времени.
develop + feature ветки должны быть корректными в любой момент времени.
все коммиты в истории всех веток должны быть корректными.
Первый вариант наиболее распространенный, дает больше свободы разработчикам и меньше давит на них.
Второй вариант имеет смысл если над feature веткой работают два разработчика одновременно, или когда ветка отдельно деплоится для тестирования.
Третий вариант самый строгий. В общем он естественный если только делать merge. Но в случае rebase всегда гарантировать синтаксическую и логическую корректность каждого rebase-нутого коммита становится очень сложно.
Мой метод rebase-а подходит для 1 и 2 вариантов: upstream всегда рабочий, все мерджи в upstream несут только корректный дифф, feature ветки тоже корректны в любой момент времени (можно сбилдить и протестировать).
Минус моего метода в том, что если сделать checkout какого-то промежуточного коммита, то он может не сбилдится, то есть 3 вариант отпадает. Только как правило в этом нет необходимости.
Есть несколько моментов. Допустим, на ветке 15 коммитов и она готова для merge-а. В общем случае, заранее неизвестно будут ли конфликты и в каком объеме. Если история коммитов не важна, то да, можно просто сквошить все 15 коммитов в один большой коммит, и там уже не важно merge или rebase, это будет один и тот же большой конфликт.
Но в большинстве случаев история отдельных коммитов важна, а точнее, их диффы и описание диффов. Однако каждый коммит может привести к отдельному конфликту при rebase. Обычно эти конфликты исправляются вручную по мере продвижения rebase-a, и целью является новый корректный код , что часто приводит к потере оригинального кода. Получается, что описание диффа старое, а код в нем новый, но это является нормой в классическом подходе. Из других минусов по сравнению с merge - нужно больше времени на исправление конфликтов и сложность в оценке суммарной работы.
Смысл данного метода в моментальной оценке работы по исправлению конфликтов и максимальная экономия времени на исправление, это достигается за счет merge-а. При этом сохраняется вся оригинальная история коммитов и оригинальный код, даже если он уже устарел. Это подходит не всем, и тогда нужен обычный rebase.
Обратный дифф не вычисляется, точнее после безусловного ребейза проект полностью заменяется корректным состоянием после сделанного merge-a, поэтому возникает дополнительный коммит. Но его легко убрать, соединив с предыдущим коммитом.
Xeon / EPYC это обычные CPU, поэтому скорость генерации токенов будет слишком медленная, по несколько секунд на одно слово, тогда как Apple Silicon это несколько слов в секунду. Энергопотребление тоже не в пользу Intel / AMD.
Фактически, компьютеры от Apple - единственные на рынке с большим объемом RAM памяти, которая доступна не только CPU, но и GPU. В общем, это и есть unified memory и это идеально подходит для локального LLM inference: чаты, кодинг.
Вместо git push --force лучше всегда делать git push --force-with-lease. В чем разница? Допустим вы с Васей работаете над одной общей веткой и хотите исправить текст нового коммита, который вы только что отправили, но если Вася в это время отправил свой коммит, то git push --force просто молча выкинет его коммит из истории на сервере, потому что ваш репозиторий его не видит. Тогда как git push --force-with-lease запрещает переписывание ветки, если там есть новые чужие коммиты. Я лично использую алиас git pf.
Сделать сразу грамотную архитектуру, писать только качественный код обычно нереально. Настоящие бизнес требования, которые приносят прибыль, находятся только после множества релизов.
Согласен, я сам разработчик, так всегда и происходит. Только я никого не оправдываю и не обвиняю. Замедление скорости доставки под грузом старой архитектуры и качества кода - это, к сожалению, нормально. Бизнес редко выбирает риск переписывания системы с нуля.
С точки зрения сетевого стэка тут про 4 уровня: L4/L3 (TCP/IP), L6 (TLS) и L7 (HTTP). Входящие на сервер запросы от клиента можно различать по каждому уровню отдельно.
Между 1000 разных клиентов IP адрес может быть общим, но исходящие TCP порты всегда будут разными. И если провайдер держит TCP соединение (а он по идее должен), то комбинация IP-port (socket) не меняются пока клиент (или сервер) явно не закроют соединение или клиент потеряет связь.
TLS handshake будет различаться по набору клиентских алгоритмов, но как измерение для fingerprint оно не очень уникальное.
HTTP уровню в целом без разницы что происходит на нижних уровнях даже если они делают TCP reconnect. И тут сессия клиента после логина сохраняется с помощью http header (уникальный cookie -> user id). Без логина тоже можно присвоить уникальный cookie. Остальные http headers могут быть разными, но не являются уникальным fingerprint.
Если парсер выдает себя за обычный браузер, то его блокировка уже нетривиальная задача, но есть разные методы борьбы с ними.
Я надеялся, что он вам пригодится, поэтому написал такой подробный комментарий. Теперь вы можно сделать алиас для этой хитрой команды.
Я попробовал "Обратный локальный мерж" на моем небольшом демо репозитории.
Во-первых, тут происходит схлопывание всей истории ветки в один коммит поверх ветки main. То есть по сути rebase + squash.
Во-вторых, мне пришлось явно выйти из мерджа:
И я также согласен, что форс-пуш лучше избегать. Можно изменить этот подход без потери истории, не создавая rebase, и не делая форс-пуш.
В общем я использовал тот же прием, про который писал на Хабре тут и тут.
Когда 3 года назад произошел большой взрыв технологии LLM, компьютеры Apple оказались единственными способными на быстрый inference моделей малого и среднего размера за счёт unified memory для CPU и GPU с колоссальной пропускной способностью. К сожалению, до сих пор нет нормальной альтернативы, а Mac Studio с большим объемом памяти просто убрали из продажи. Компания Apple опять на коне. Ещё бы была поддержка CUDA, то их рабочие станции стали бы золотым стандартом для исследователей и разработчиков в сфере AI.
Линус Торвальдс много раз объяснял почему Linux на C и в нём никогда не будет C++. И одна из причин было то, что он не хочет, чтобы код в его проекте писали C++ программисты. При этом Rust был им допущен и уже есть в исходниках Linux.
Каждый коммит в git описывает состояние проекта целиком и полностью, а видимый diff всегда вычисляется динамически. Коммит это дерево проекта (tree) + метаданные, более подробно в моей статье тут.
Слишком хорош для запуска LLM.
Более полный список интерфейсов
Субъективно, Waymo ездит очень аккуратно, по всем правилам, но как робот, теряется в нетипичных ситуациях. Я думаю, что аварийность значительно меньше, чем у Uber.
Интересно, а что будет после его ухода и многолетней диктатуры? Демократия разработчиков? Олигополия больших корпораций? Добавят С++ или ZFS?
Если разработчик лично предпочитает merge, но на текущем проекте всем нужно делать rebase, то в таком случае данный метод это очень хороший компромисс.
И я согласен, что rebase требует большей квалификации и понимания, чем merge. И что rebase противоречит оригинальной идеологии git, что все коммиты должны быть иммутабельны.
Допустим, общая ветка (upstream) это develop, есть три варианта насколько строго требовать корректность коммитов в репозитории на сервере:
develop должен быть корректным в любой момент времени.
develop + feature ветки должны быть корректными в любой момент времени.
все коммиты в истории всех веток должны быть корректными.
Первый вариант наиболее распространенный, дает больше свободы разработчикам и меньше давит на них.
Второй вариант имеет смысл если над feature веткой работают два разработчика одновременно, или когда ветка отдельно деплоится для тестирования.
Третий вариант самый строгий. В общем он естественный если только делать merge. Но в случае rebase всегда гарантировать синтаксическую и логическую корректность каждого rebase-нутого коммита становится очень сложно.
Мой метод rebase-а подходит для 1 и 2 вариантов: upstream всегда рабочий, все мерджи в upstream несут только корректный дифф, feature ветки тоже корректны в любой момент времени (можно сбилдить и протестировать).
Минус моего метода в том, что если сделать checkout какого-то промежуточного коммита, то он может не сбилдится, то есть 3 вариант отпадает. Только как правило в этом нет необходимости.
Я имел в виду, что работа по исправлению конфликтов становится одинаковой между merge и rebase в предельном случае, когда в ветке всего один коммит.
Есть несколько моментов. Допустим, на ветке 15 коммитов и она готова для merge-а. В общем случае, заранее неизвестно будут ли конфликты и в каком объеме. Если история коммитов не важна, то да, можно просто сквошить все 15 коммитов в один большой коммит, и там уже не важно merge или rebase, это будет один и тот же большой конфликт.
Но в большинстве случаев история отдельных коммитов важна, а точнее, их диффы и описание диффов. Однако каждый коммит может привести к отдельному конфликту при rebase. Обычно эти конфликты исправляются вручную по мере продвижения rebase-a, и целью является новый корректный код , что часто приводит к потере оригинального кода. Получается, что описание диффа старое, а код в нем новый, но это является нормой в классическом подходе. Из других минусов по сравнению с merge - нужно больше времени на исправление конфликтов и сложность в оценке суммарной работы.
Смысл данного метода в моментальной оценке работы по исправлению конфликтов и максимальная экономия времени на исправление, это достигается за счет merge-а. При этом сохраняется вся оригинальная история коммитов и оригинальный код, даже если он уже устарел. Это подходит не всем, и тогда нужен обычный rebase.
Обратный дифф не вычисляется, точнее после безусловного ребейза проект полностью заменяется корректным состоянием после сделанного merge-a, поэтому возникает дополнительный коммит. Но его легко убрать, соединив с предыдущим коммитом.
Мне кажется, что это дело вкуса и привычки. Я тоже раньше думал, что тру программист должен выбирать терминал.
Xeon / EPYC это обычные CPU, поэтому скорость генерации токенов будет слишком медленная, по несколько секунд на одно слово, тогда как Apple Silicon это несколько слов в секунду. Энергопотребление тоже не в пользу Intel / AMD.
Фактически, компьютеры от Apple - единственные на рынке с большим объемом RAM памяти, которая доступна не только CPU, но и GPU. В общем, это и есть unified memory и это идеально подходит для локального LLM inference: чаты, кодинг.
Вместо
git push --forceлучше всегда делатьgit push --force-with-lease. В чем разница? Допустим вы с Васей работаете над одной общей веткой и хотите исправить текст нового коммита, который вы только что отправили, но если Вася в это время отправил свой коммит, тоgit push --forceпросто молча выкинет его коммит из истории на сервере, потому что ваш репозиторий его не видит. Тогда какgit push --force-with-leaseзапрещает переписывание ветки, если там есть новые чужие коммиты. Я лично использую алиасgit pf.Сделать сразу грамотную архитектуру, писать только качественный код обычно нереально. Настоящие бизнес требования, которые приносят прибыль, находятся только после множества релизов.
Согласен, я сам разработчик, так всегда и происходит. Только я никого не оправдываю и не обвиняю. Замедление скорости доставки под грузом старой архитектуры и качества кода - это, к сожалению, нормально. Бизнес редко выбирает риск переписывания системы с нуля.