مطالب
Build Events
در ویژوال استودیو یک ویژگی جالب با عنوان Pre/Post-Build Event وجود دارد. این ویژگی به رویدادهای «قبل از بیلد» و «بعد از بیلد» اشاره دارد. از این ویژگی برای اجرای یکسری دستورات، قبل (Pre-build) یا بعد (Post-build) از عملیات بیلد استفاده میشود. دستوراتی که در این قسمت قابل اجرا هستند دقیقا همانند دستورات موجود در یک batch فایل میباشند. حتی میتوان یک فایل bat. را در این قسمت فراخوانی کرد. بطور خلاصه هرگونه دستوری که درون Command Prompt ویندوز یا در یک bat. فایل قابل اجرا باشد در این قسمت نیز قابل استفاده است. درنهایت تمام این دستورات توسط برنامه Cmd.exe اجرا میشوند.
نکته: قبل از ادامه بهتر است به این نکته اشاره کنم که مجموعه این دستورات چیزی فراتر از فراخوانی ساده یکسری فایل exe. هستند. درواقع کدی که در این قسمت به آن اشاره میشود، دارای ساختاری به صورت یک زبان برنامه نویسی ساده است. یعنی متن نهایی‌ای که برای اجرا به cmd.exe ارسال میشود میتواند شامل دستورات ساده و اولیه برنامه نویسی چون if .. then .. else و حلقه for و از این قبیل نیز باشد. برای آشنایی بیشتر با زبان این نوع دستورات به منابع زیر مراجعه کنید:

تنظیم رویدادهای بیلد (Build Events)
برای تنظیم این رویدادها باید به تب Build Events در صفحه پراپرتی‌های پروژه موردنظر مراجعه کنید. همانند تصویر زیر در یک پروژه کنسول #C:

البته در پروژه‌های VB.NET مسیر منتهی به این قسمت کمی فرق میکند که در تصویر زیر نشان داده شده است:

در پروژه‌های مربوط به زبانهای دیگر هم مسیر رسیدن به این رویدادها کمی متفاوت است. برای کسب اطلاعات بیشتر به اینجا مراجعه کنید.
در این قسمت میتوان همانند یک فایل batch دستورات موردنظر را در خطوط مجزا برای اجرا اضافه کرد. از این دستورات معمولا برای مدیریت عملیات بیلد، کپی فایلهای موردنیاز قبل یا بعد از بیلد، پاک کردن فولدرها، تغییر برخی تنظیمات با توجه به نوع کانفیگ بیلد (Debug یا Release)، ثبت یک اسمبلی در GAC و یا حتی اجرای برخی آزمونهای واحد و ... استفاده میشود.

نکته: درصورتیکه پروژه به روز باشد (یعنی ویژوال استودیو نیازی به تولید فایل اسمبلی نهایی پروژه به دلیل عدم وجود تغییری در کد برنامه نبیند) بدلیل عدم اجرای عملیات بید، دستورات قسمت Pre-build اجرا نمیشوند. اجرای دستورات قسمت Post-build نیز بستگی به تنظیمات قسمت :Run the post-build events همانند تصویر زیر دارد:

برای استفاده راحتتر از این ویژگی فرمی مخصوص وارد کردن این دستورات در ویژوال استودیو وجود دارد. برای دیدن این فرم بر روی دکمه ...Edit Pre-build یا ...Edit Post-build کلیک کنید. پنجره زیر نمایش داده میشود:

در این پنجره میتوان دستورات مورد نظر را وارد کرد. با اینکه هیچ امکان خاصی برای کمک به اضافه و ویرایش دستورات در این پنجره وجود ندارد! اما تنها ویژگی موجود در این فرم کمک بسیاری برای تکمیل دستورات موردنظر میکند. قبل از توضیح این ویژگی بهتر است با مفهوم Macro در این قسمت آشنا شویم.
 
Macro
در Build Events ویژوال استودیو یکسری متغیرهای ازقبل تعریف شده وجود دارد که به آنها Macro گفته میشود. برای مشاهده لیست این ماکروها روی دکمه << Macro کلیک کنید. پنجره مربوطه به صورت زیر گسترش می‌یابد تا جدولی به نام Macro Table را نمایش دهد:

همانطور که مشاهده میکنید تعداد 19 ماکرو به همراه مقادیرشان در این قسمت به نمایش گذاشته شده است. برای استفاده از این ماکروها کافی است تا روی یکی از آنها دابل کلیک کنید یا پس از انتخاب ماکروی موردنظر روی دکمه Insert کلیک کنید. دقت کنید که نحوه نمایش این ماکروها در متن دستورات به صورت زیر است:
$(<Macro_Name>)
که به جای عبارت <Macro_Name> عنوان ماکرو قرار میگیرد. مثلا:
$(OutDir)   یا   $(ProjectName)
نکته: نام این ماکروها case-sensitive نیست.

نحوه اجرای دستورات توسط ویژوال استودیو
ویژوال استودیو برای اجرای دستورات کار خاصی به صورت مستقیم انجام نمیدهد! وظیفه اصلی برعهده MSBuild (^) است. این ابزار پس از جایگزین کردن مقادیر ماکروها، محتوای کل دستورات موجود در هر یک از رویدادها را در یک فایل batch ذخیره میکند و فایل مربوط به هر رویداد را در زمان خودش به اجرا میگذارد. مثلا دستور زیر را درنظر بگیرید:
Copy $(OutDir)*.* %WinDir%
پس از ذخیره در فایل batch نهایی به صورت زیر در خواهد آمد:
Copy bin\Debug\*.* %WinDir%
نکته: در این زبان برنامه نویسی، عبارتی چون %WinDir% معرف یک متغیر است. در این مورد خاص این عبارت یک متغیر محیطی (Environment Variable) است. اطلاعات بیشتر در اینجا.

MSBuild عملیات اجرای این batch فایلهای تولیدی را زیر نظر دارد و هرگونه خطای موجود در این دستورات را به عنوان خطای زمان بیلد گزارش میدهد. اما از آنجاکه کل دستورات مربوط به هر رویداد درون یک فایل batch اجرا میشود، امکان گزارش محل دقیق خطای رخداده وجود ندارد. یعنی درصورتیکه مثلا تنها یکی از صدها خط دستور نوشته شده در این قسمت خطا بدهد تنها یک خطا و برای تمام دستورات نمایش داده میشود. البته همانطور که حدس میتوان حدس زد اجرای این دستورات ترنزکشنال نیست و اجرای تمامی دستورات تا قبل از وقوع خطا برگشت ناپذیر خواهند بود. برای نمونه به تصویر زیر و خطای نمایش داده شده دقت کنید:

نمونه اصلاح شده دستور فوق به صورت زیر است:
Copy "$(ProjectDir)$(OutDir)*.*" c:\test
نکته: به دلیل استفاده از کاراکتر فاصله به عنوان جداکننده آرگومانها در دستورات DOS، وجود فاصله در مسیرهای مورد استفاده در این دستورات عملیات را دچار خطا خواهد کرد. راه‌حل استفاده از کاراکتر " در ابتدا و انتهای رشته‌های مربوط به مسیرها همانند دستور بالاست.
نکته: درصورت استفاده از یک فایل bat. برای ذخیره دستورات، امکان استفاده مستقیم از ماکروهای ویژوال استودیو درون آن وجود نخواهد داشت! یکی از راه‌حلها پاس کردن این متغیرها به صورت پارامتر در زمان فراخوانی فایل bat. است. مثلا:
"$(ProjectDir)postBuild.bat"   "$(SolutionPath)"
برای دریافت این پارامترهای پاس شده درون batch فایل باید از عبارات 1% برای پارامتر اول و 2% برای پارامتر دوم و ... تا 9% برای پارامتر نهم است. برای کسب اطلاعات بیشتر به منابع معرفی شده در ابتدای مطلب مخصوصا قسمت Using batch parameters مراجعه کنید.
 
حال مجموعه دستورات زیر و خطای رخ داده را درنظر بگیرید:

با بررسی مطلب متوجه میشویم با اینکه خط اول مجموعه دستورات فوق درست بوده و کاملا صحیح اجرا میشود اما خطای رخ داده به کل دستورات اشاره دارد و مشخص نشده است که کدام دستور مشکل دارد. دقت کنید که دستور اول کاملا اجرا میشود!
راه حل ساده ای در اینجا برای حل این مشکل ارائه شده است. در این راه حل با استفاده از قابلیتهای این زبان، کل عملیات و مخصوصا خطاهای رخ داده در این مجموعه دستورات هندل میشود تا کنترل بهتری در این مورد بر روی فرایند وجود داشته باشد. نمونه این راه حل به صورت زیر است:
echo ---------------------------------------------------------------------------
echo Copy "$(ProjectDir)$(OutDir)*.*" c:\test --Starting...
Copy "$(ProjectDir)$(OutDir)*.*" c:\test
if errorlevel 1 goto error
echo Copy "$(ProjectDir)$(OutDir)*.*" c:\test --DONE!
echo ---------------------------------------------------------------------------
echo ---------------------------------------------------------------------------
echo Copy $(OutDir)*.* c:\test --Starting...
Copy $(OutDir)*.* c:\test
if errorlevel 1 goto error
echo Copy $(OutDir)*.* c:\test --DONE!
echo ---------------------------------------------------------------------------
goto ok
:error
echo POSTBUILDSTEP for $(ProjectName) FAILED
notepad.exe
exit 1
:ok
echo POSTBUILDSTEP for $(ProjectName) COMPLETED OK
با استفاده از مجموعه دستوراتی شبیه دستورات بالا میتوان لحظه به لحظه اجرای عملیات را بررسی کرد.
نکته: خروجی تمام این دستورات و نیز خروجی دستورات echo در پنجره Output ویژوال استودیو به همراه سایر پیغامهای بیلد نمایش داده میشود.
نکته: در اسکرپیت فوق برای درک بیشتر مسئله با استفاده از دستور notepad.exe در قسمت error: از وقوع خطا اطمینان حاصل میشود. دقت کنید تا زمانیکه برنامه اجرا شده Notepad بسته نشود فوکس به ویژوال استودیو برنمیگردد و عملیات بیلد تمام نمیشود.
نکته: درصورت استفاده از دستور exit 0 در انتهای قسمت error: (به جای دستور exit 1 موجود) به دلیل اعلام خروج موفق از عملیات، ویژوال استودیو خطایی نمایش نخواهد داد و عملیات بیلد بدون نمایش خطا و با موفقیت به پایان خواهد رسید. درواقع استفاده از هر عددی غیر از صفر به معنی خروج با خطا است که این عدد غیرصفر کد خطا یا error level را مشخص میکند (^ و ^).

یکی از دستورات جالبی که میتوان در این رویدادها از آن استفاده کرد، دستور نصب نسخه ریلیز برنامه در GAC است. نحوه استفاده از آن میتواند به صورت زیر باشد:
if $(ConfigurationName) == Release (
gacutil.exe /i "$(SolutionDir)$(OutDir)$(TargetFileName)"
)

نکته: درصورتیکه در دستورات مربوط به رویداد قبل از بیلد یعنی Pre-build خطایی رخ بدهد عملیات بیلد متوقف خواهد شد و برای پروژه فایلی تولید نمیشود. اما اگر این خطا در رویداد بعد از بیلد یعنی Post-build رخ دهد با اینکه ویژوال استودیو وقوع یک خطا را گزارش میدهد اما فایلهای خروجی پروژه حاصله از عملیات بیلد تولید خواهند شد.
نکته: توجه داشته باشید که در استفاه از این ویژگی زیاده‌روی نباید کرد. استفاده زیاد و بیش از حد (و با تعداد زیاد دستورات) از این رویدادها ممکن است عملیات بیلد را دچار مشکلاتی پیچیده کند. دیباگ این رویدادها و دستورات موجود در آنها بسیار مشکل خواهد بود. اگر تعداد خطوط دستورات موردنظر زیاد باشد بهتر است کل دستورات را درون یک فایل bat. ذخیره کنید و این فایل را بطور جداگانه مدیریت کنید که کار راحتتری است.
نکته: بهتر است قبل از وارد کردن دستورات درون این رویدادها، ابتدا تمام دستورات را در یک پنجره cmd آزمایش کنید تا از درستی ساختار و نتیجه آن‌ها مطمئن شوید.

رویدادهای بیلد و MSBuild
همانطور که در اینجا توضیح داده شده است، ویژوال استودیو از ابزار MSBuild برای تولید اپلیکیشنها استفاده میکند. عملیات مدیریت رویدادهای بیلد نیز توسط این ابزار انجام میشود. اگر به فایل پروژه مربوط به مثال قبل مراجعه کنید به محتوایی شبیه خطوط زیر میرسید:
...
<PropertyGroup>
<PostBuildEvent>echo ---------------------------------------------------------------------------
echo Copy "$(ProjectDir)$(OutDir)*.*" c:\test --Starting...
Copy "$(ProjectDir)$(OutDir)*.*" c:\test
if errorlevel 1 goto error
echo Copy "$(ProjectDir)$(OutDir)*.*" c:\test --DONE!
echo ---------------------------------------------------------------------------
echo ---------------------------------------------------------------------------
echo Copy $(OutDir)*.* c:\test --Starting...
Copy $(OutDir)*.* c:\test
if errorlevel 1 goto error
echo Copy $(OutDir)*.* c:\test --DONE!
echo ---------------------------------------------------------------------------
goto ok
:error
echo POSTBUILDSTEP for $(ProjectName) FAILED
notepad.exe
exit 1
:ok
echo POSTBUILDSTEP for $(ProjectName) COMPLETED OK</PostBuildEvent>
</PropertyGroup>
...
همانطور که میبینید در ویژوال استودیو تنها ذخیره این تنظیمات در فایل پروژه انجام میشود و کلیه عملیات توسط ابزار MSBuild مدیریت میگردد. امکان بهر برداری از این رویدادها با استفاده مستقیم از ابزار MSBuild نیز وجود دارد اما به دلیل مفصل بودن بحث، جستجوی بیشتر به خوانندگان واگذار میشود.
منابع برای مطالعه بیشتر:
مطالب
تعامل MATLAB (متلب) با دات نت - قسمت دوم
در قسمت قبل در مورد استفاده دات نت در متلب توضیح داده شد. در این قسمت به نحوه استفاده توابع متلب در دات نت بصورت ساده می‌پردازیم.
فرض کنید تیم برنامه‌نویس متلب و تیم برنامه‌نویس دات نت در تعامل با یکدیگر هستند. وظیفه تیم برنامه نویسی متلب به شرح زیر می‌باشد :

1- نوشتن توابع در متلب و تست کردن آنها جهت توسعه و ارائه مناسب به تیم مقابل
2- درست کردن کامپوننت دات نت در متلب با استفاده از محیط  Deployment Tool GUI  (با اجرای دستور deploytool در متلب)
3- استفاده از یک پکیج بسته‌بندی شده از فایل‌های قابل ارائه به تیم مقابل (اختیاری)
4- کپی پکیج در محل از قبل تعیین شده توسط دو تیم یا ارائه آن به تیم مقابل جهت استفاده

برای مثال M فایل (اصطلاح فایل‌ها در متلب همانند کلاس در دات نت) makesquare.m را که در مسیر
matlabroot\toolbox\dotnetbuilder\Examples\VS8\NET\MagicSquareExample\MagicSquareComp
است را در نظر بگیرید :  
function y = makesquare(x)
%MAKESQUARE Magic square of size x.
%   Y = MAKESQUARE(X) returns a magic square of size x.
%   This file is used as an example for the MATLAB 
%   Builder NE product.

%   Copyright 2001-2012 The MathWorks, Inc.

y = magic(x);
تابع majic یک ماتریس در ابعاد x در x درست می‌کند که درایه‌های آن اعداد صحیح از 1 تا X^2 بوده و مجموع سطر و ستون‌های آن با هم برابر است. X باید بزرگتر یا مساوی 3 باشد.
در صورتی که x  برابر 5 انتخاب شود خروجی متلب بصورت زیر خواهد بود :
17 24  1  8 15
23  5  7 14 16
 4  6 13 20 22
10 12 19 21  3
11 18 25  2  9
در قسمت تهیه یک کامپوننت دات نت اطلاعات زیر را در نظر بگیرید :
 
 makeSqr  
 Project Name 
 MLTestClass 
Class Name 
 makesquare.m  File to compile 
سپس برای درست کردن کامپوننت در محیط  Deployment Tool GUI برنامه متلب را اجرا کرده و در پنجره command دستور deploytool  را اجرا کنید تا پنجره زیر باز شود :

نام و مسیر پروژه را تعیین کنید سپس از منوی کشویی نوع پروژه، که دات نت اسمبلی باشد را انتخاب کنید. پنجره‌ای در به شکل زیر مشاهده خواهد شد : 

در تب build اگر قصد استفاده از اپلیکیشن COM را دارید و یا فایل‌هایی جهت تکمیل پروژه قصد پیوست دارید را در قسمت پایین Add files را انتخاب کنید. و اگر قصد استفاده از اپلیکیشن دات نت را دارید قسمت بالایی Add classes را انتخاب کنید و نام کلاس را وارد کنید.

سپس برای کلاس مورد نظر فایل‌های متلبی که قصد کامپایل کردن آنها را دارید از قسمت Add files پیوست کنید. در صورتیکه قصد اضافه کردن کلاس اضافی را داشتید مجددا مراحل را طی کنید. در انتها دکمه build را زده تا عملیات کامپایل آغاز شود. اما برای استفاده تیم برنامه‌نویسی دات نت احتیاج به کامپایلر متلب می‌باشد که این مهم در پکیجی که به این تیم ارائه خواهد شد مد نظر قرار خواهد گرفت.در قسمت تب Package گزینه Add MCR را انتخاب نمائید :

بعد از انتخاب، دو گزینه برای انتخاب وجود دارد که بطور خلاصه گزینه اول فایل‌های کامپایلر متلب در داخل پروژه جهت ارائه قرار می‌گیرد. همچنین این گزینه جهت استفاده در مواقع درون شبکه‌ای، مواردی که فضای دیسک و عملکرد و .... چندان اهمیت ندارد مورد استفاده قرار می‌گیرد. اما گزینه دوم عکس قضیه بالا عمل می‌کند و برای تعداد یوزر بالا و شبکه‌ای و ... مورد استفاده می‌باشد.

در اینجا گزینه اول را انتخاب می‌کنیم. در صورتیکه فایل‌های دیگری جهت ضمیمه به پکیج احتیاج است به آن اضافه می‌کینم.

سپس کلید پکیج  را زده تا پکیج مورد نظر آماده شود. دقت داشته باشید که بعد از انتخاب کامپایلر متلب، حجم پکیج نزدیک به 400 مگابایت خواهد شد. پکیج مورد نظر بصورت یک فایل exe فشرده خواهد شد.
معمولا پکیج شامل فایل‌های زیر باید باشد :

 Documentation files   componentName.xml 
 Program Database File, which contains debugging information   componentName.pdb (if Debug optionis selected)
 Component assembly file   componentName.dll 
 MCR Installer (if not already installed on the target machine).   MCR Installer 

بعد از طی مراحل فوق نوبت به تیم برنامه‌نویسی دات نت می‌رسد. بعد از دریافت پکیج از تیم برنامه‌نویسی متلب در صورتیکه بر روی سیستم هدف کامپایلر متلب و یا خود متلب نصب نیست باید از داخل پکیج این کامپایلر نصب شود.
دقت داشته باشید که ورژن کامپایلر بر روی سیستم باید با ورژن پکیج دریافتی یکی باشد.
در VS یک پروژه کنسول ایجاد کنید و از فولدر پکیج پروژه دریافتی در زیرفولدر distrib فایل makeSqr.dll را به رفرنس برنامه VS اضافه کنید.
در ادامه از مسیر نصب کامپایلر فایل MWArray.dll را هم به رفرنس پروژه اضافه کنید. این فایل جهت تبادل داده اپلیکیشن با کامپایلر متلب مورد استفاده قرار می‌گیرد.

installation_folder\toolbox\dotnetbuilder\bin\architecture\framework_version
اسمبلی‌های زیر را به کلاس Program  برنامه اضافه کنید :
using System;
using MathWorks.MATLAB.NET.Arrays;
using MyComponentName;
سپس کدهای زیر را به کلاس فوق اضافه نمائید :
static void Main(string[] args)
        {
            MLTestClass obj = new MLTestClass();
            MWArray[] result = obj.makesquare(1, 5);

            MWNumericArray output = (MWNumericArray)result[0];
            Console.WriteLine(output);

        }
توضیحات کدهای فوق :
1- MWNumericArray یک اینترفیس جهت تعیین و نمایش نوع آرایه‌های عددی در متلب است.
2- MWArray یک کلاس abstract جهت دسترسی، فرمت‌دهی و مدیریت آرایه‌های متلب می‌باشد.
3- عدد 1 مشخص کننده تعداد خروجی تابع متلب و عدد 5 ورودی تابع می‌باشد.

خروجی برنامه همانند خروجی متلب بصورت زیر خواهد بود :

نکته:
ورژن فریمورک دات نت در هنگام کامپایل با ورژن Mwarray.dll باید یکی باشد.

نظرات مطالب
ساخت یک سایت ساده‌‌ی نمایش لیست فیلم با استفاده از Vue.js - قسمت اول
با تشکر؛ فقط این نکته رو اشاره کنم در تکمیل مقاله دوستمون و اونم اینه که حتما باید ابزار عبور از تحریم فعال باشه برای اجرای دستور
npm install -g @vue/cli

چون طبق تصویر زیر ممکنه با خطای زیر مواجه بشین

نظرات مطالب
مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. - قسمت چهارم - پرهیز از الگوی Service Locator در برنامه‌های وب
نکته تکمیلی :
در مقاله گفته شده که میتوان از خاصیت [FromServices] را بر روی Property داخل Model استفاده کرد (property injection)
طبق مستندات دات نت، خاصیت [FromServices] فقط بر روی Parameter قابل استفاده است و نه Property 
در واقع این امکان برای نسخه beta بوده و خیلی وقت است که منسوخ شده   است. ^  ^
نظرات مطالب
کش کردن اطلاعات غیر پویا در ASP.Net - قسمت چهارم
من مشکل رو در iis7 در ویندوز 7 میبینم و نکته دیگه اینکه در ii6 و ویندوز سرور 2003 هم کار نکرده و با اینکه این چند روز خیلی دنبال این مسئله تو اینترنت بودم حدود 70 مقاله که اکثرا شبیه به هم بودند رو بررسی کردم حتی iis7 رو دوباره نصب کردم ولی مشکل همچنان باقیست.
مطالب
7# آموزش سیستم مدیریت کد Git : بازیابی فایل

در این مقاله با یکی از مهمترین ویژگی‌های git یعنی بازیابی تغییرات فایل‌ها، آشنا می‌شویم. اما در ابتدا نگاهی می‌کنیم به چگونگی ایجاد تغییر در آخرین commit:


تغییر آخرین commit:
در git این امکان وجود دارد که آخرین فرمان commit با استفاده از اصلاح‌کننده amend تغییر کند. علت تاکید بر روی آخرین دستور این است که git به دلیل ساختاری که دارد نمی‌تواند commit‌های قبل را تغییر دهد. اگر مقالات ابتدایی آموزش git را مطالعه کرده باشید، به خاطر دارید که هر commit دارای یک کد منحصر به فرد SHA-1 است، که این کد از هش کردن BLOBها به همراه خود مقادیر commit یعنی مشخصات ایجاد کننده آن و از همه مهمتر SHA-1 پدر ایجاد می‌شود. در نتیجه تغییر commitیی که نقش برگ را ندارد، یعنی در ساختار درختی git دارای فرزند است، سبب می‌شود کد SHA-1 آن تغییر کند. این تغییر، commit‌های فرزند را مجاب می‌کند برای حفظ صحت داده‌ها مقدار SHA-1 خود را تغییر دهند. به این ترتیب این تغییرات در کل repository پخش خواهد شد. به همین دلیل git جز آخرین commit امکان اصلاح دیگر commit‌ها را نخواهد داد.
برای اصلاح آخرین commit کافی است دستور commit خود را با amend-- بیاورید

دستورات بازیابی فایل:

دستور checkout:
این فرمان یکی از مهمترین فرمان‌های git است که دارای دو کاربرد است:
۱) بازیابی فایلی از repository و یا stage
۲) تغییر شاخه (این مورد را در مقالات مربوط به branch بررسی خواهیم کرد)
با استفاده از این دستور می‌توان فایلی را از repository به stage یا working tree و یا هر دو بیاوریم. عملکرد این دستور با اصلاح کننده‌های گوناگون متفاوت خواهد بود. در ادامه روش‌های مختلف فراخوانی این دستور و کاربرد هر کدام آورده شده است:
در صورتی که بخواهیم فایلی را از محلی که head اکنون به آن اشاره می‌کند به working tree بیاوریم از دستور زیر استفاده می‌کنیم:

git checkout --[filename]

در حالت فوق فایل مستقیما به working tree آورده شده و در stage قرار نمی‌گیرد

تذکر: -- در دستور بالا اختیاری بوده، اما استفاده از آن توصیه می‌شود. زیرا در صورتی‌که نام فایل به اشتباه وارد شود و یا فایل موجود نباشد، git اقدام به تعویض شاخه می‌کند. زیرا همانطور که گفته شد، این دستور کاربرد دوگانه دارد.
در این حالت ممکن است به علت سهل انگاری مشکلاتی ایجاد شود علامت -- تاکید می‌کند که مقدار نوشته نام فایل است.
حال اگر بخواهیم فایلی را از commit‌های قبل بازیابی کنیم، می‌توانیم از دستور زیر استفاده کنیم:

git checkout [SHA-1] [filename]

در این حالت فایل هم در stage و هم در working tree قرار می‌گیرد.



دستور reset:
در صورتی‌که بخواهید تعداد زیادی فایل را به وضعیت مشخصی در زمان قبل برگدانید، reset فرمان مناسبی خواهد بود. البته استفاده از این دستور باید با احتیاط کامل صورت گیرد. زیرا در صورت اشتباه، این امکان وجود دارد که دیگر نتوانید به بخشی از سوابق فایل‌های خود دسترسی داشته باشید. بنابراین این دستور همان‌قدر که کاربردی است، به همان اندازه نیز خطرناک است.
دستور reset را می‌توان به ۳ صورت اجرا نمود:
۱) soft
۲) mixed (حالت پیشفرض)
۳) hard
۱)در حالت soft تنها head به commit گفته شده منتقل می‌شود و working tree و همچنین stage تغییری نمی‌کند. دقیقا مانند آن‌که هد یک نوار خوان ویدئویی به جای آن‌که به آخرین محل ضبط اشاره کند، به عقب برگشته و به قسمتی در قبل برود. در این حالت در صورتی‌که دستور commit جدیدی ایجاد نشود که باعث پاک شدن  commitهای از آن‌جا به بعد شود، می‌توان با اجرای مجدد دستور reset و اشاره به آخرین commit، مجددا head را به سر جای اول برگرداند. البته توجه کنید در صورتی‌که در هنگام برگرداندن head به commit‌های قبلی، فایل‌هایی تغییر کرده باشند، آن‌ها به صورت خودکار به stage اضافه می‌شوند.
۲) در حالت mixed که پیش فرض این دستور نیز است، working tree بدون تغییر می‌ماند. اما stage تغییر کرده و دقیقا مانند وضعیت commit می‌شود.
۳) در این حالت هم working tree و هم stage تغییر می‌کند و عینا وضعیت commitیی را می‌گیرند که اکنون head به آن اشاره می‌کند. استفاده از این اصلاح کننده بسیار خطرناک‌تر از موارد قبل است.
در هر یک از موارد فوق تا زمانی‌که دستور commit جدیدی را اجرا نکرده باشید، می‌توانید به وضعیت قبل برگردید. اما اگر commit جدید اجرا شود دیگر امکان بازگشت به commit‌های صورت گرفته بعد از آن وجود ندارد.

نکته مهم:

علیرغم آن‌که می‌توان به commit‌های گذشته در صورت عدم داشتن commit جدید مراجعه کرد، اما یک اشکال فنی وجود دارد و آن این است که شما نمی‌توانید SHA-1‌های آن commitها را با دستوراتی نظیر log ببینید. بنابراین بهتر است مقدار آن‌ها را قبل از اجرای دستور، ذخیره و تا اطمینان از وضعیت فعلی در محلی نگه دارید.

شکل زیر نمایانگر وضعیت‏‌های مختلف دستور reset در هنگام بازگشت به سه commit قبل نسبت به وضعیت فعلی Head است:



 

نظرات مطالب
آشنایی با jQuery Live
ممنون؛ نکته بسیار خوبی بود
اشتراک‌ها
آیا ویندوز 11 در راه است

مایکروسافت اخیرا یک ویدیو از صدای کاهش سرعت داده شده (تا 4000 درصد) مربوط به ملودی استارتاپ نسخه‌ها گذشته ویندوز منتشر کرده و خبر از رویدادی مهم در تاریخ 24 ژوئن داده است. از انجا که این مدت این ویدیو 11 دقیقه است و ساعت شروع رویداد هم ساعت 11 می‌باشد، خیلی‌ها این گمانه زنی را می‌کنند که ویندوز 11 در راه است.

آیا ویندوز 11 در راه است
مطالب
پشتیبانی از Generic Attributes در C# 11
هر کلاسی در #C که از کلاس پایه‌ی System.Attribute مشتق شود، یک Attribute نامیده می‌شود و مهم‌ترین و هدف و کاربرد آن‌ها، مزین کردن و علامتگذاری سایر نوع‌ها و فیلدها هستند تا بر اساس آن‌ها بتوان کارکردهای بیشتری را در اختیار آن نوع‌ها قرار داد. برای مثال، استفاده از  ویژگی‌‌های JsonProperty و یا JsonPropertyName در حین اعمال serializations و یا در کاربردهای اعتبارسنجی مانند ویژگی‌های Required، Range و امثال آن‌ها:
public class Student
{
    [JsonPropertyName("id")]
    public int Id { get; set; }

    [JsonPropertyName("name")]
    public string Name { get; set; }
}

public class WeatherForecast
{
    [Required]
    public int TemperatureC { get; set; }

    [MinLength(50)]
    public string Summary { get; set; }
}

روش متداول ارسال نوع‌ها به attributes تا پیش از C# 11

تا پیش از C# 11، روش پیاده سازی یک attribute جنریک که بتواند با انواع و اقسام نوع‌ها کار کند، به صورت زیر است:
- ارسال یک پارامتر از نوع System.Type به سازنده‌ی attribute
- تعریف خاصیتی مانند ParamType در صورت نیاز؛ تا مشخص کند که چه نوعی به سازنده‌ی attribute ارسال شده‌است. مانند مثال فرضی زیر:
[AttributeUsage(AttributeTargets.Class)]
public class CustomDoNothingAttribute: Attribute
{
    // Note the type parameter in the constructor
    public CustomDoNothingAttribute(Type t)
    {
        ParamType = t;
    }

    public Type ParamType { get; }
}
و سپس با استفاده از عملگر typeof، نوع مدنظر را به سازنده‌ی ویژگی تعریف شده، ارسال می‌کنیم:
[CustomDoNothing(typeof(string))]
public class Student
{
    public int Id { get; set; }

    public string Name { get; set; }
}
یک نمونه مثال دنیای واقعی آن، [ServiceFilter(typeof(ResponseLoggerFilter))] در ASP.NET Core است که دیگر با وجود جنریک‌ها، آنچنان هماهنگ و یک‌دست با سایر اجزای زبان به نظر نمی‌رسد. نمونه‌ی هماهنگ با پیشرفت‌های زبان، باید چنین شکلی را داشته باشد: [<ServiceFilter<ResponseLoggerFilter]


امکان تعریف ویژگی‌های جنریک در C# 11

‍C# 11 به همراه پیشتیبانی از generic attributes ارائه شده‌است. بنابراین اینبار بجای ارسال پارمتری از نوع Type به سازنده‌ی ویژگی‌، می‌توان کلاس آن attribute را به صورت جنریک تعریف کنیم که می‌تواند یک یا چندین نوع را به عنوان پارامتر بپذیرد. بنابراین مثال قبل در C# 11 به صورت زیر بازنویسی می‌شود:
[AttributeUsage(AttributeTargets.Class)]
public class CustomDoNothingAttribute<T> : Attribute
    where T : class
{
    public T ParamType { get; }
}

[CustomDoNothing<string>]
public class Student
{
    public int Id { get; set; }

    public string Name { get; set; }
}
یک مزیت مهم این روش نسبت به قبل، امکان تعریف قیود و type safety است. برای نمونه در مثال فوق، نوع T به کلاس‌ها محدود شده‌است و نوع‌های دیگر را نمی‌پذیرد. به این ترتیب می‌توان این نوع بررسی‌ها را بجای زمان اجرا و صدور استثناءها، دقیقا در زمان کامپایل انجام داد.
و اگر نیاز به تعیین چند نوع بود، باید خاصیت AllowMultiple نحوه‌ی استفاده از ویژگی را به true تنظیم کرد:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class DecorateAttribute<T> : Attribute where T : class
{
    // ....
}
تا بتوان به تعریف زیر رسید:
[Decorate<LoggerDecorator>]
[Decorate<TimerDecorator>]
public class SimpleWorker
{
    // ....
}


محدودیت‌های انتخاب نوع‌ها در ویژگی‌های جنریک C# 11

در ویژگی‌های جنریک نمی‌توان از نوع‌های زیر استفاده کرد (همان محدودیت‌های typeof، در اینجا هم برقرار هستند):
- نوع‌های dynamic
- nullable reference types مانند ?string
- نوع‌های tuple تعریف شده‌ی به کمک C# tuple syntax مانند (int x, int y)

چون این نوع‌ها به همراه یکسری metadata annotations هستند که صرفا بیانگر توضیحی اضافی در مورد نوع بکارگرفته شده هستند و در صورت نیاز، بجای آن‌ها می‌توانید از نوع‌های زیر استفاده کنید:
- از object بجای dynamic
- از string بجای ?string
- از <ValueTuple<int, int بجای (int X, int Y)

همچنین در زمان استفاده‌ی از یک ویژگی جنریک، باید نوع مورد استفاده، کاملا مشخص و در اصطلاح fully constructed باشد:
public class GenericAttribute<T> : Attribute { }

public class GenericType<T>
{
    [GenericAttribute<T>] // Not allowed! generic attributes must be fully constructed types.
    public string Method1() => default;

    [GenericAttribute<string>]
    public string Method2() => default;
}